Update remaining Amicale screens to use TypeScript

This commit is contained in:
Arnaud Vergnet 2020-09-22 19:50:31 +02:00
parent 67cb96dd03
commit d70f22bdae
3 changed files with 116 additions and 114 deletions

View file

@ -17,24 +17,18 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {FlatList, Image, Linking, View} from 'react-native'; import {FlatList, Image, Linking, View} from 'react-native';
import {Card, List, Text, withTheme, Avatar} from 'react-native-paper'; import {Avatar, Card, List, Text} from 'react-native-paper';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
import type {MaterialCommunityIconsGlyphs} from 'react-native-vector-icons/MaterialCommunityIcons';
import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList'; import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
import AMICALE_LOGO from '../../../assets/amicale.png';
import type { const AMICALE_LOGO = require('../../../assets/amicale.png');
CardTitleIconPropsType,
ListIconPropsType,
} from '../../constants/PaperStyles';
type DatasetItemType = { type DatasetItemType = {
name: string, name: string;
email: string, email: string;
icon: MaterialCommunityIconsGlyphs, icon: string;
}; };
/** /**
@ -45,7 +39,7 @@ class AmicaleContactScreen extends React.Component<null> {
CONTACT_DATASET: Array<DatasetItemType>; CONTACT_DATASET: Array<DatasetItemType>;
constructor() { constructor() {
super(); super(null);
this.CONTACT_DATASET = [ this.CONTACT_DATASET = [
{ {
name: i18n.t('screens.amicaleAbout.roles.interSchools'), name: i18n.t('screens.amicaleAbout.roles.interSchools'),
@ -97,7 +91,13 @@ class AmicaleContactScreen extends React.Component<null> {
keyExtractor = (item: DatasetItemType): string => item.email; keyExtractor = (item: DatasetItemType): string => item.email;
getChevronIcon = (iconProps: ListIconPropsType): React.Node => ( getChevronIcon = (iconProps: {
color: string;
style?: {
marginRight: number;
marginVertical?: number;
};
}) => (
<List.Icon <List.Icon
color={iconProps.color} color={iconProps.color}
style={iconProps.style} style={iconProps.style}
@ -105,7 +105,7 @@ class AmicaleContactScreen extends React.Component<null> {
/> />
); );
getRenderItem = ({item}: {item: DatasetItemType}): React.Node => { getRenderItem = ({item}: {item: DatasetItemType}) => {
const onPress = () => { const onPress = () => {
Linking.openURL(`mailto:${item.email}`); Linking.openURL(`mailto:${item.email}`);
}; };
@ -113,7 +113,7 @@ class AmicaleContactScreen extends React.Component<null> {
<List.Item <List.Item
title={item.name} title={item.name}
description={item.email} description={item.email}
left={(iconProps: ListIconPropsType): React.Node => ( left={(iconProps) => (
<List.Icon <List.Icon
color={iconProps.color} color={iconProps.color}
style={iconProps.style} style={iconProps.style}
@ -126,7 +126,7 @@ class AmicaleContactScreen extends React.Component<null> {
); );
}; };
getScreen = (): React.Node => { getScreen = () => {
return ( return (
<View> <View>
<View <View
@ -148,7 +148,7 @@ class AmicaleContactScreen extends React.Component<null> {
<Card.Title <Card.Title
title={i18n.t('screens.amicaleAbout.title')} title={i18n.t('screens.amicaleAbout.title')}
subtitle={i18n.t('screens.amicaleAbout.subtitle')} subtitle={i18n.t('screens.amicaleAbout.subtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => ( left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="information" /> <Avatar.Icon size={iconProps.size} icon="information" />
)} )}
/> />
@ -165,7 +165,7 @@ class AmicaleContactScreen extends React.Component<null> {
); );
}; };
render(): React.Node { render() {
return ( return (
<CollapsibleFlatList <CollapsibleFlatList
data={[{key: '1'}]} data={[{key: '1'}]}
@ -176,4 +176,4 @@ class AmicaleContactScreen extends React.Component<null> {
} }
} }
export default withTheme(AmicaleContactScreen); export default AmicaleContactScreen;

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {Image, KeyboardAvoidingView, StyleSheet, View} from 'react-native'; import {Image, KeyboardAvoidingView, StyleSheet, View} from 'react-native';
import { import {
@ -29,32 +27,33 @@ import {
withTheme, withTheme,
} from 'react-native-paper'; } from 'react-native-paper';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
import {StackNavigationProp} from '@react-navigation/stack'; import {StackNavigationProp, StackScreenProps} from '@react-navigation/stack';
import LinearGradient from 'react-native-linear-gradient'; import LinearGradient from 'react-native-linear-gradient';
import ConnectionManager from '../../managers/ConnectionManager'; import ConnectionManager from '../../managers/ConnectionManager';
import ErrorDialog from '../../components/Dialogs/ErrorDialog'; import ErrorDialog from '../../components/Dialogs/ErrorDialog';
import type {CustomThemeType} from '../../managers/ThemeManager';
import AsyncStorageManager from '../../managers/AsyncStorageManager'; import AsyncStorageManager from '../../managers/AsyncStorageManager';
import AvailableWebsites from '../../constants/AvailableWebsites'; import AvailableWebsites from '../../constants/AvailableWebsites';
import {MASCOT_STYLE} from '../../components/Mascot/Mascot'; import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
import MascotPopup from '../../components/Mascot/MascotPopup'; import MascotPopup from '../../components/Mascot/MascotPopup';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView'; import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
import {MainStackParamsList} from '../../navigation/MainNavigator';
type PropsType = { type LoginScreenNavigationProp = StackScreenProps<MainStackParamsList, 'login'>;
navigation: StackNavigationProp,
route: {params: {nextScreen: string}}, type Props = LoginScreenNavigationProp & {
theme: CustomThemeType, navigation: StackNavigationProp<any>;
theme: ReactNativePaper.Theme;
}; };
type StateType = { type StateType = {
email: string, email: string;
password: string, password: string;
isEmailValidated: boolean, isEmailValidated: boolean;
isPasswordValidated: boolean, isPasswordValidated: boolean;
loading: boolean, loading: boolean;
dialogVisible: boolean, dialogVisible: boolean;
dialogError: number, dialogError: number;
mascotDialogVisible: boolean, mascotDialogVisible: boolean;
}; };
const ICON_AMICALE = require('../../../assets/amicale.png'); const ICON_AMICALE = require('../../../assets/amicale.png');
@ -82,17 +81,21 @@ const styles = StyleSheet.create({
}, },
}); });
class LoginScreen extends React.Component<PropsType, StateType> { class LoginScreen extends React.Component<Props, StateType> {
onEmailChange: (value: string) => void; onEmailChange: (value: string) => void;
onPasswordChange: (value: string) => void; onPasswordChange: (value: string) => void;
passwordInputRef: {current: null | TextInput}; passwordInputRef: {
// @ts-ignore
current: null | TextInput;
};
nextScreen: string | null; nextScreen: string | null;
constructor(props: PropsType) { constructor(props: Props) {
super(props); super(props);
this.nextScreen = null;
this.passwordInputRef = React.createRef(); this.passwordInputRef = React.createRef();
this.onEmailChange = (value: string) => { this.onEmailChange = (value: string) => {
this.onInputChange(true, value); this.onInputChange(true, value);
@ -158,8 +161,9 @@ class LoginScreen extends React.Component<PropsType, StateType> {
* @returns {*} * @returns {*}
*/ */
onEmailSubmit = () => { onEmailSubmit = () => {
if (this.passwordInputRef.current != null) if (this.passwordInputRef.current != null) {
this.passwordInputRef.current.focus(); this.passwordInputRef.current.focus();
}
}; };
/** /**
@ -188,7 +192,7 @@ class LoginScreen extends React.Component<PropsType, StateType> {
* *
* @returns {*} * @returns {*}
*/ */
getFormInput(): React.Node { getFormInput() {
const {email, password} = this.state; const {email, password} = this.state;
return ( return (
<View> <View>
@ -239,7 +243,7 @@ class LoginScreen extends React.Component<PropsType, StateType> {
* Gets the card containing the input form * Gets the card containing the input form
* @returns {*} * @returns {*}
*/ */
getMainCard(): React.Node { getMainCard() {
const {props, state} = this; const {props, state} = this;
return ( return (
<View style={styles.card}> <View style={styles.card}>
@ -248,7 +252,7 @@ class LoginScreen extends React.Component<PropsType, StateType> {
titleStyle={{color: '#fff'}} titleStyle={{color: '#fff'}}
subtitle={i18n.t('screens.login.subtitle')} subtitle={i18n.t('screens.login.subtitle')}
subtitleStyle={{color: '#fff'}} subtitleStyle={{color: '#fff'}}
left={({size}: {size: number}): React.Node => ( left={({size}) => (
<Image <Image
source={ICON_AMICALE} source={ICON_AMICALE}
style={{ style={{
@ -349,20 +353,18 @@ class LoginScreen extends React.Component<PropsType, StateType> {
AsyncStorageManager.PREFERENCES.homeShowMascot.key, AsyncStorageManager.PREFERENCES.homeShowMascot.key,
false, false,
); );
if (this.nextScreen == null) navigation.goBack(); if (this.nextScreen == null) {
else navigation.replace(this.nextScreen); navigation.goBack();
} else {
navigation.replace(this.nextScreen);
}
}; };
/** /**
* Saves the screen to navigate to after a successful login if one was provided in navigation parameters * Saves the screen to navigate to after a successful login if one was provided in navigation parameters
*/ */
handleNavigationParams() { handleNavigationParams() {
const {route} = this.props; this.nextScreen = this.props.route.params.nextScreen;
if (route.params != null) {
if (route.params.nextScreen != null)
this.nextScreen = route.params.nextScreen;
else this.nextScreen = null;
}
} }
/** /**
@ -417,7 +419,7 @@ class LoginScreen extends React.Component<PropsType, StateType> {
return this.isEmailValid() && this.isPasswordValid() && !loading; return this.isEmailValid() && this.isPasswordValid() && !loading;
} }
render(): React.Node { render() {
const {mascotDialogVisible, dialogVisible, dialogError} = this.state; const {mascotDialogVisible, dialogVisible, dialogError} = this.state;
return ( return (
<LinearGradient <LinearGradient
@ -441,7 +443,6 @@ class LoginScreen extends React.Component<PropsType, StateType> {
message={i18n.t('screens.login.mascotDialog.message')} message={i18n.t('screens.login.mascotDialog.message')}
icon="help" icon="help"
buttons={{ buttons={{
action: null,
cancel: { cancel: {
message: i18n.t('screens.login.mascotDialog.button'), message: i18n.t('screens.login.mascotDialog.button'),
icon: 'check', icon: 'check',

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {FlatList, StyleSheet, View} from 'react-native'; import {FlatList, StyleSheet, View} from 'react-native';
import { import {
@ -38,42 +36,37 @@ import MaterialHeaderButtons, {
Item, Item,
} from '../../components/Overrides/CustomHeaderButton'; } from '../../components/Overrides/CustomHeaderButton';
import CardList from '../../components/Lists/CardList/CardList'; import CardList from '../../components/Lists/CardList/CardList';
import type {CustomThemeType} from '../../managers/ThemeManager';
import AvailableWebsites from '../../constants/AvailableWebsites'; import AvailableWebsites from '../../constants/AvailableWebsites';
import Mascot, {MASCOT_STYLE} from '../../components/Mascot/Mascot'; import Mascot, {MASCOT_STYLE} from '../../components/Mascot/Mascot';
import ServicesManager, {SERVICES_KEY} from '../../managers/ServicesManager'; import ServicesManager, {SERVICES_KEY} from '../../managers/ServicesManager';
import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList'; import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
import type {ServiceItemType} from '../../managers/ServicesManager'; import type {ServiceItemType} from '../../managers/ServicesManager';
import type {
CardTitleIconPropsType,
ListIconPropsType,
} from '../../constants/PaperStyles';
type PropsType = { type PropsType = {
navigation: StackNavigationProp, navigation: StackNavigationProp<any>;
theme: CustomThemeType, theme: ReactNativePaper.Theme;
}; };
type StateType = { type StateType = {
dialogVisible: boolean, dialogVisible: boolean;
}; };
type ClubType = { type ClubType = {
id: number, id: number;
name: string, name: string;
is_manager: boolean, is_manager: boolean;
}; };
type ProfileDataType = { type ProfileDataType = {
first_name: string, first_name: string;
last_name: string, last_name: string;
email: string, email: string;
birthday: string, birthday: string;
phone: string, phone: string;
branch: string, branch: string;
link: string, link: string;
validity: boolean, validity: boolean;
clubs: Array<ClubType>, clubs: Array<ClubType>;
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -89,7 +82,7 @@ const styles = StyleSheet.create({
}); });
class ProfileScreen extends React.Component<PropsType, StateType> { class ProfileScreen extends React.Component<PropsType, StateType> {
data: ProfileDataType; data: ProfileDataType | null;
flatListData: Array<{id: string}>; flatListData: Array<{id: string}>;
@ -97,6 +90,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
constructor(props: PropsType) { constructor(props: PropsType) {
super(props); super(props);
this.data = null;
this.flatListData = [{id: '0'}, {id: '1'}, {id: '2'}, {id: '3'}]; this.flatListData = [{id: '0'}, {id: '1'}, {id: '2'}, {id: '3'}];
const services = new ServicesManager(props.navigation); const services = new ServicesManager(props.navigation);
this.amicaleDataset = services.getAmicaleServices([SERVICES_KEY.PROFILE]); this.amicaleDataset = services.getAmicaleServices([SERVICES_KEY.PROFILE]);
@ -117,7 +111,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* *
* @returns {*} * @returns {*}
*/ */
getHeaderButton = (): React.Node => ( getHeaderButton = () => (
<MaterialHeaderButtons> <MaterialHeaderButtons>
<Item <Item
title="logout" title="logout"
@ -133,12 +127,9 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* @param data The data fetched from the server * @param data The data fetched from the server
* @returns {*} * @returns {*}
*/ */
getScreen = (data: Array<ProfileDataType | null>): React.Node => { getScreen = (data: Array<ProfileDataType | null>) => {
const {dialogVisible} = this.state; const {dialogVisible} = this.state;
const {navigation} = this.props; this.data = data[0];
// eslint-disable-next-line prefer-destructuring
if (data[0] != null) this.data = data[0];
return ( return (
<View style={{flex: 1}}> <View style={{flex: 1}}>
<CollapsibleFlatList <CollapsibleFlatList
@ -146,7 +137,6 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
data={this.flatListData} data={this.flatListData}
/> />
<LogoutDialog <LogoutDialog
navigation={navigation}
visible={dialogVisible} visible={dialogVisible}
onDismiss={this.hideDisconnectDialog} onDismiss={this.hideDisconnectDialog}
/> />
@ -154,7 +144,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
); );
}; };
getRenderItem = ({item}: {item: {id: string}}): React.Node => { getRenderItem = ({item}: {item: {id: string}}) => {
switch (item.id) { switch (item.id) {
case '0': case '0':
return this.getWelcomeCard(); return this.getWelcomeCard();
@ -172,7 +162,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* *
* @returns {*} * @returns {*}
*/ */
getServicesList(): React.Node { getServicesList() {
return <CardList dataset={this.amicaleDataset} isHorizontal />; return <CardList dataset={this.amicaleDataset} isHorizontal />;
} }
@ -181,15 +171,15 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* *
* @returns {*} * @returns {*}
*/ */
getWelcomeCard(): React.Node { getWelcomeCard() {
const {navigation} = this.props; const {navigation} = this.props;
return ( return (
<Card style={styles.card}> <Card style={styles.card}>
<Card.Title <Card.Title
title={i18n.t('screens.profile.welcomeTitle', { title={i18n.t('screens.profile.welcomeTitle', {
name: this.data.first_name, name: this.data?.first_name,
})} })}
left={(): React.Node => ( left={() => (
<Mascot <Mascot
style={{ style={{
width: 60, width: 60,
@ -233,8 +223,8 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* @param field The field to get the value from * @param field The field to get the value from
* @return {*} * @return {*}
*/ */
static getFieldValue(field: ?string): string { static getFieldValue(field?: string): string {
return field != null ? field : i18n.t('screens.profile.noData'); return field ? field : i18n.t('screens.profile.noData');
} }
/** /**
@ -244,7 +234,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* @param icon The icon to use * @param icon The icon to use
* @return {*} * @return {*}
*/ */
getPersonalListItem(field: ?string, icon: string): React.Node { getPersonalListItem(field: string | undefined, icon: string) {
const {theme} = this.props; const {theme} = this.props;
const title = field != null ? ProfileScreen.getFieldValue(field) : ':('; const title = field != null ? ProfileScreen.getFieldValue(field) : ':(';
const subtitle = field != null ? '' : ProfileScreen.getFieldValue(field); const subtitle = field != null ? '' : ProfileScreen.getFieldValue(field);
@ -252,7 +242,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
<List.Item <List.Item
title={title} title={title}
description={subtitle} description={subtitle}
left={(props: ListIconPropsType): React.Node => ( left={(props) => (
<List.Icon <List.Icon
style={props.style} style={props.style}
icon={icon} icon={icon}
@ -268,14 +258,14 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* *
* @return {*} * @return {*}
*/ */
getPersonalCard(): React.Node { getPersonalCard() {
const {theme, navigation} = this.props; const {theme, navigation} = this.props;
return ( return (
<Card style={styles.card}> <Card style={styles.card}>
<Card.Title <Card.Title
title={`${this.data.first_name} ${this.data.last_name}`} title={`${this.data?.first_name} ${this.data?.last_name}`}
subtitle={this.data.email} subtitle={this.data?.email}
left={(iconProps: CardTitleIconPropsType): React.Node => ( left={(iconProps) => (
<Avatar.Icon <Avatar.Icon
size={iconProps.size} size={iconProps.size}
icon="account" icon="account"
@ -290,10 +280,10 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
<List.Subheader> <List.Subheader>
{i18n.t('screens.profile.personalInformation')} {i18n.t('screens.profile.personalInformation')}
</List.Subheader> </List.Subheader>
{this.getPersonalListItem(this.data.birthday, 'cake-variant')} {this.getPersonalListItem(this.data?.birthday, 'cake-variant')}
{this.getPersonalListItem(this.data.phone, 'phone')} {this.getPersonalListItem(this.data?.phone, 'phone')}
{this.getPersonalListItem(this.data.email, 'email')} {this.getPersonalListItem(this.data?.email, 'email')}
{this.getPersonalListItem(this.data.branch, 'school')} {this.getPersonalListItem(this.data?.branch, 'school')}
</List.Section> </List.Section>
<Divider /> <Divider />
<Card.Actions> <Card.Actions>
@ -303,7 +293,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
onPress={() => { onPress={() => {
navigation.navigate('website', { navigation.navigate('website', {
host: AvailableWebsites.websites.AMICALE, host: AvailableWebsites.websites.AMICALE,
path: this.data.link, path: this.data?.link,
title: i18n.t('screens.websites.amicale'), title: i18n.t('screens.websites.amicale'),
}); });
}} }}
@ -321,14 +311,14 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* *
* @return {*} * @return {*}
*/ */
getClubCard(): React.Node { getClubCard() {
const {theme} = this.props; const {theme} = this.props;
return ( return (
<Card style={styles.card}> <Card style={styles.card}>
<Card.Title <Card.Title
title={i18n.t('screens.profile.clubs')} title={i18n.t('screens.profile.clubs')}
subtitle={i18n.t('screens.profile.clubsSubtitle')} subtitle={i18n.t('screens.profile.clubsSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => ( left={(iconProps) => (
<Avatar.Icon <Avatar.Icon
size={iconProps.size} size={iconProps.size}
icon="account-group" icon="account-group"
@ -339,7 +329,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
/> />
<Card.Content> <Card.Content>
<Divider /> <Divider />
{this.getClubList(this.data.clubs)} {this.getClubList(this.data?.clubs)}
</Card.Content> </Card.Content>
</Card> </Card>
); );
@ -350,14 +340,14 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* *
* @return {*} * @return {*}
*/ */
getMembershipCar(): React.Node { getMembershipCar() {
const {theme} = this.props; const {theme} = this.props;
return ( return (
<Card style={styles.card}> <Card style={styles.card}>
<Card.Title <Card.Title
title={i18n.t('screens.profile.membership')} title={i18n.t('screens.profile.membership')}
subtitle={i18n.t('screens.profile.membershipSubtitle')} subtitle={i18n.t('screens.profile.membershipSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => ( left={(iconProps) => (
<Avatar.Icon <Avatar.Icon
size={iconProps.size} size={iconProps.size}
icon="credit-card" icon="credit-card"
@ -368,7 +358,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
/> />
<Card.Content> <Card.Content>
<List.Section> <List.Section>
{this.getMembershipItem(this.data.validity)} {this.getMembershipItem(this.data?.validity === true)}
</List.Section> </List.Section>
</Card.Content> </Card.Content>
</Card> </Card>
@ -380,7 +370,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* *
* @return {*} * @return {*}
*/ */
getMembershipItem(state: boolean): React.Node { getMembershipItem(state: boolean) {
const {theme} = this.props; const {theme} = this.props;
return ( return (
<List.Item <List.Item
@ -389,7 +379,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
? i18n.t('screens.profile.membershipPayed') ? i18n.t('screens.profile.membershipPayed')
: i18n.t('screens.profile.membershipNotPayed') : i18n.t('screens.profile.membershipNotPayed')
} }
left={(props: ListIconPropsType): React.Node => ( left={(props) => (
<List.Icon <List.Icon
style={props.style} style={props.style}
color={state ? theme.colors.success : theme.colors.danger} color={state ? theme.colors.success : theme.colors.danger}
@ -406,18 +396,25 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* @param item The club to render * @param item The club to render
* @return {*} * @return {*}
*/ */
getClubListItem = ({item}: {item: ClubType}): React.Node => { getClubListItem = ({item}: {item: ClubType}) => {
const {theme} = this.props; const {theme} = this.props;
const onPress = () => { const onPress = () => {
this.openClubDetailsScreen(item.id); this.openClubDetailsScreen(item.id);
}; };
let description = i18n.t('screens.profile.isMember'); let description = i18n.t('screens.profile.isMember');
let icon = (props: ListIconPropsType): React.Node => ( let icon = (props: {
color: string;
style: {
marginLeft: number;
marginRight: number;
marginVertical?: number;
};
}) => (
<List.Icon color={props.color} style={props.style} icon="chevron-right" /> <List.Icon color={props.color} style={props.style} icon="chevron-right" />
); );
if (item.is_manager) { if (item.is_manager) {
description = i18n.t('screens.profile.isManager'); description = i18n.t('screens.profile.isManager');
icon = (props: ListIconPropsType): React.Node => ( icon = (props) => (
<List.Icon <List.Icon
style={props.style} style={props.style}
icon="star" icon="star"
@ -441,7 +438,11 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
* @param list The club list * @param list The club list
* @return {*} * @return {*}
*/ */
getClubList(list: Array<ClubType>): React.Node { getClubList(list: Array<ClubType> | undefined) {
if (!list) {
return null;
}
list.sort(this.sortClubList); list.sort(this.sortClubList);
return ( return (
<FlatList <FlatList
@ -473,7 +474,7 @@ class ProfileScreen extends React.Component<PropsType, StateType> {
navigation.navigate('club-information', {clubId: id}); navigation.navigate('club-information', {clubId: id});
} }
render(): React.Node { render() {
const {navigation} = this.props; const {navigation} = this.props;
return ( return (
<AuthenticatedScreen <AuthenticatedScreen