diff --git a/src/screens/Amicale/AmicaleContactScreen.js b/src/screens/Amicale/AmicaleContactScreen.tsx
similarity index 84%
rename from src/screens/Amicale/AmicaleContactScreen.js
rename to src/screens/Amicale/AmicaleContactScreen.tsx
index e924942..b7f0ae4 100644
--- a/src/screens/Amicale/AmicaleContactScreen.js
+++ b/src/screens/Amicale/AmicaleContactScreen.tsx
@@ -17,24 +17,18 @@
* along with Campus INSAT. If not, see .
*/
-// @flow
-
import * as React from 'react';
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 type {MaterialCommunityIconsGlyphs} from 'react-native-vector-icons/MaterialCommunityIcons';
import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
-import AMICALE_LOGO from '../../../assets/amicale.png';
-import type {
- CardTitleIconPropsType,
- ListIconPropsType,
-} from '../../constants/PaperStyles';
+
+const AMICALE_LOGO = require('../../../assets/amicale.png');
type DatasetItemType = {
- name: string,
- email: string,
- icon: MaterialCommunityIconsGlyphs,
+ name: string;
+ email: string;
+ icon: string;
};
/**
@@ -45,7 +39,7 @@ class AmicaleContactScreen extends React.Component {
CONTACT_DATASET: Array;
constructor() {
- super();
+ super(null);
this.CONTACT_DATASET = [
{
name: i18n.t('screens.amicaleAbout.roles.interSchools'),
@@ -97,7 +91,13 @@ class AmicaleContactScreen extends React.Component {
keyExtractor = (item: DatasetItemType): string => item.email;
- getChevronIcon = (iconProps: ListIconPropsType): React.Node => (
+ getChevronIcon = (iconProps: {
+ color: string;
+ style?: {
+ marginRight: number;
+ marginVertical?: number;
+ };
+ }) => (
{
/>
);
- getRenderItem = ({item}: {item: DatasetItemType}): React.Node => {
+ getRenderItem = ({item}: {item: DatasetItemType}) => {
const onPress = () => {
Linking.openURL(`mailto:${item.email}`);
};
@@ -113,7 +113,7 @@ class AmicaleContactScreen extends React.Component {
(
+ left={(iconProps) => (
{
);
};
- getScreen = (): React.Node => {
+ getScreen = () => {
return (
{
(
+ left={(iconProps) => (
)}
/>
@@ -165,7 +165,7 @@ class AmicaleContactScreen extends React.Component {
);
};
- render(): React.Node {
+ render() {
return (
{
}
}
-export default withTheme(AmicaleContactScreen);
+export default AmicaleContactScreen;
diff --git a/src/screens/Amicale/LoginScreen.js b/src/screens/Amicale/LoginScreen.tsx
similarity index 91%
rename from src/screens/Amicale/LoginScreen.js
rename to src/screens/Amicale/LoginScreen.tsx
index 5773425..5da8505 100644
--- a/src/screens/Amicale/LoginScreen.js
+++ b/src/screens/Amicale/LoginScreen.tsx
@@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see .
*/
-// @flow
-
import * as React from 'react';
import {Image, KeyboardAvoidingView, StyleSheet, View} from 'react-native';
import {
@@ -29,32 +27,33 @@ import {
withTheme,
} from 'react-native-paper';
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 ConnectionManager from '../../managers/ConnectionManager';
import ErrorDialog from '../../components/Dialogs/ErrorDialog';
-import type {CustomThemeType} from '../../managers/ThemeManager';
import AsyncStorageManager from '../../managers/AsyncStorageManager';
import AvailableWebsites from '../../constants/AvailableWebsites';
import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
import MascotPopup from '../../components/Mascot/MascotPopup';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
+import {MainStackParamsList} from '../../navigation/MainNavigator';
-type PropsType = {
- navigation: StackNavigationProp,
- route: {params: {nextScreen: string}},
- theme: CustomThemeType,
+type LoginScreenNavigationProp = StackScreenProps;
+
+type Props = LoginScreenNavigationProp & {
+ navigation: StackNavigationProp;
+ theme: ReactNativePaper.Theme;
};
type StateType = {
- email: string,
- password: string,
- isEmailValidated: boolean,
- isPasswordValidated: boolean,
- loading: boolean,
- dialogVisible: boolean,
- dialogError: number,
- mascotDialogVisible: boolean,
+ email: string;
+ password: string;
+ isEmailValidated: boolean;
+ isPasswordValidated: boolean;
+ loading: boolean;
+ dialogVisible: boolean;
+ dialogError: number;
+ mascotDialogVisible: boolean;
};
const ICON_AMICALE = require('../../../assets/amicale.png');
@@ -82,17 +81,21 @@ const styles = StyleSheet.create({
},
});
-class LoginScreen extends React.Component {
+class LoginScreen extends React.Component {
onEmailChange: (value: string) => void;
onPasswordChange: (value: string) => void;
- passwordInputRef: {current: null | TextInput};
+ passwordInputRef: {
+ // @ts-ignore
+ current: null | TextInput;
+ };
nextScreen: string | null;
- constructor(props: PropsType) {
+ constructor(props: Props) {
super(props);
+ this.nextScreen = null;
this.passwordInputRef = React.createRef();
this.onEmailChange = (value: string) => {
this.onInputChange(true, value);
@@ -158,8 +161,9 @@ class LoginScreen extends React.Component {
* @returns {*}
*/
onEmailSubmit = () => {
- if (this.passwordInputRef.current != null)
+ if (this.passwordInputRef.current != null) {
this.passwordInputRef.current.focus();
+ }
};
/**
@@ -188,7 +192,7 @@ class LoginScreen extends React.Component {
*
* @returns {*}
*/
- getFormInput(): React.Node {
+ getFormInput() {
const {email, password} = this.state;
return (
@@ -239,7 +243,7 @@ class LoginScreen extends React.Component {
* Gets the card containing the input form
* @returns {*}
*/
- getMainCard(): React.Node {
+ getMainCard() {
const {props, state} = this;
return (
@@ -248,7 +252,7 @@ class LoginScreen extends React.Component {
titleStyle={{color: '#fff'}}
subtitle={i18n.t('screens.login.subtitle')}
subtitleStyle={{color: '#fff'}}
- left={({size}: {size: number}): React.Node => (
+ left={({size}) => (
{
AsyncStorageManager.PREFERENCES.homeShowMascot.key,
false,
);
- if (this.nextScreen == null) navigation.goBack();
- else navigation.replace(this.nextScreen);
+ if (this.nextScreen == null) {
+ navigation.goBack();
+ } else {
+ navigation.replace(this.nextScreen);
+ }
};
/**
* Saves the screen to navigate to after a successful login if one was provided in navigation parameters
*/
handleNavigationParams() {
- const {route} = this.props;
- if (route.params != null) {
- if (route.params.nextScreen != null)
- this.nextScreen = route.params.nextScreen;
- else this.nextScreen = null;
- }
+ this.nextScreen = this.props.route.params.nextScreen;
}
/**
@@ -417,7 +419,7 @@ class LoginScreen extends React.Component {
return this.isEmailValid() && this.isPasswordValid() && !loading;
}
- render(): React.Node {
+ render() {
const {mascotDialogVisible, dialogVisible, dialogError} = this.state;
return (
{
message={i18n.t('screens.login.mascotDialog.message')}
icon="help"
buttons={{
- action: null,
cancel: {
message: i18n.t('screens.login.mascotDialog.button'),
icon: 'check',
diff --git a/src/screens/Amicale/ProfileScreen.js b/src/screens/Amicale/ProfileScreen.tsx
similarity index 81%
rename from src/screens/Amicale/ProfileScreen.js
rename to src/screens/Amicale/ProfileScreen.tsx
index b35b401..ac98621 100644
--- a/src/screens/Amicale/ProfileScreen.js
+++ b/src/screens/Amicale/ProfileScreen.tsx
@@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see .
*/
-// @flow
-
import * as React from 'react';
import {FlatList, StyleSheet, View} from 'react-native';
import {
@@ -38,42 +36,37 @@ import MaterialHeaderButtons, {
Item,
} from '../../components/Overrides/CustomHeaderButton';
import CardList from '../../components/Lists/CardList/CardList';
-import type {CustomThemeType} from '../../managers/ThemeManager';
import AvailableWebsites from '../../constants/AvailableWebsites';
import Mascot, {MASCOT_STYLE} from '../../components/Mascot/Mascot';
import ServicesManager, {SERVICES_KEY} from '../../managers/ServicesManager';
import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
import type {ServiceItemType} from '../../managers/ServicesManager';
-import type {
- CardTitleIconPropsType,
- ListIconPropsType,
-} from '../../constants/PaperStyles';
type PropsType = {
- navigation: StackNavigationProp,
- theme: CustomThemeType,
+ navigation: StackNavigationProp;
+ theme: ReactNativePaper.Theme;
};
type StateType = {
- dialogVisible: boolean,
+ dialogVisible: boolean;
};
type ClubType = {
- id: number,
- name: string,
- is_manager: boolean,
+ id: number;
+ name: string;
+ is_manager: boolean;
};
type ProfileDataType = {
- first_name: string,
- last_name: string,
- email: string,
- birthday: string,
- phone: string,
- branch: string,
- link: string,
- validity: boolean,
- clubs: Array,
+ first_name: string;
+ last_name: string;
+ email: string;
+ birthday: string;
+ phone: string;
+ branch: string;
+ link: string;
+ validity: boolean;
+ clubs: Array;
};
const styles = StyleSheet.create({
@@ -89,7 +82,7 @@ const styles = StyleSheet.create({
});
class ProfileScreen extends React.Component {
- data: ProfileDataType;
+ data: ProfileDataType | null;
flatListData: Array<{id: string}>;
@@ -97,6 +90,7 @@ class ProfileScreen extends React.Component {
constructor(props: PropsType) {
super(props);
+ this.data = null;
this.flatListData = [{id: '0'}, {id: '1'}, {id: '2'}, {id: '3'}];
const services = new ServicesManager(props.navigation);
this.amicaleDataset = services.getAmicaleServices([SERVICES_KEY.PROFILE]);
@@ -117,7 +111,7 @@ class ProfileScreen extends React.Component {
*
* @returns {*}
*/
- getHeaderButton = (): React.Node => (
+ getHeaderButton = () => (
- {
* @param data The data fetched from the server
* @returns {*}
*/
- getScreen = (data: Array): React.Node => {
+ getScreen = (data: Array) => {
const {dialogVisible} = this.state;
- const {navigation} = this.props;
- // eslint-disable-next-line prefer-destructuring
- if (data[0] != null) this.data = data[0];
-
+ this.data = data[0];
return (
{
data={this.flatListData}
/>
@@ -154,7 +144,7 @@ class ProfileScreen extends React.Component {
);
};
- getRenderItem = ({item}: {item: {id: string}}): React.Node => {
+ getRenderItem = ({item}: {item: {id: string}}) => {
switch (item.id) {
case '0':
return this.getWelcomeCard();
@@ -172,7 +162,7 @@ class ProfileScreen extends React.Component {
*
* @returns {*}
*/
- getServicesList(): React.Node {
+ getServicesList() {
return ;
}
@@ -181,15 +171,15 @@ class ProfileScreen extends React.Component {
*
* @returns {*}
*/
- getWelcomeCard(): React.Node {
+ getWelcomeCard() {
const {navigation} = this.props;
return (
(
+ left={() => (
{
* @param field The field to get the value from
* @return {*}
*/
- static getFieldValue(field: ?string): string {
- return field != null ? field : i18n.t('screens.profile.noData');
+ static getFieldValue(field?: string): string {
+ return field ? field : i18n.t('screens.profile.noData');
}
/**
@@ -244,7 +234,7 @@ class ProfileScreen extends React.Component {
* @param icon The icon to use
* @return {*}
*/
- getPersonalListItem(field: ?string, icon: string): React.Node {
+ getPersonalListItem(field: string | undefined, icon: string) {
const {theme} = this.props;
const title = field != null ? ProfileScreen.getFieldValue(field) : ':(';
const subtitle = field != null ? '' : ProfileScreen.getFieldValue(field);
@@ -252,7 +242,7 @@ class ProfileScreen extends React.Component {
(
+ left={(props) => (
{
*
* @return {*}
*/
- getPersonalCard(): React.Node {
+ getPersonalCard() {
const {theme, navigation} = this.props;
return (
(
+ title={`${this.data?.first_name} ${this.data?.last_name}`}
+ subtitle={this.data?.email}
+ left={(iconProps) => (
{
{i18n.t('screens.profile.personalInformation')}
- {this.getPersonalListItem(this.data.birthday, 'cake-variant')}
- {this.getPersonalListItem(this.data.phone, 'phone')}
- {this.getPersonalListItem(this.data.email, 'email')}
- {this.getPersonalListItem(this.data.branch, 'school')}
+ {this.getPersonalListItem(this.data?.birthday, 'cake-variant')}
+ {this.getPersonalListItem(this.data?.phone, 'phone')}
+ {this.getPersonalListItem(this.data?.email, 'email')}
+ {this.getPersonalListItem(this.data?.branch, 'school')}
@@ -303,7 +293,7 @@ class ProfileScreen extends React.Component {
onPress={() => {
navigation.navigate('website', {
host: AvailableWebsites.websites.AMICALE,
- path: this.data.link,
+ path: this.data?.link,
title: i18n.t('screens.websites.amicale'),
});
}}
@@ -321,14 +311,14 @@ class ProfileScreen extends React.Component {
*
* @return {*}
*/
- getClubCard(): React.Node {
+ getClubCard() {
const {theme} = this.props;
return (
(
+ left={(iconProps) => (
{
/>
- {this.getClubList(this.data.clubs)}
+ {this.getClubList(this.data?.clubs)}
);
@@ -350,14 +340,14 @@ class ProfileScreen extends React.Component {
*
* @return {*}
*/
- getMembershipCar(): React.Node {
+ getMembershipCar() {
const {theme} = this.props;
return (
(
+ left={(iconProps) => (
{
/>
- {this.getMembershipItem(this.data.validity)}
+ {this.getMembershipItem(this.data?.validity === true)}
@@ -380,7 +370,7 @@ class ProfileScreen extends React.Component {
*
* @return {*}
*/
- getMembershipItem(state: boolean): React.Node {
+ getMembershipItem(state: boolean) {
const {theme} = this.props;
return (
{
? i18n.t('screens.profile.membershipPayed')
: i18n.t('screens.profile.membershipNotPayed')
}
- left={(props: ListIconPropsType): React.Node => (
+ left={(props) => (
{
* @param item The club to render
* @return {*}
*/
- getClubListItem = ({item}: {item: ClubType}): React.Node => {
+ getClubListItem = ({item}: {item: ClubType}) => {
const {theme} = this.props;
const onPress = () => {
this.openClubDetailsScreen(item.id);
};
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;
+ };
+ }) => (
);
if (item.is_manager) {
description = i18n.t('screens.profile.isManager');
- icon = (props: ListIconPropsType): React.Node => (
+ icon = (props) => (
{
* @param list The club list
* @return {*}
*/
- getClubList(list: Array): React.Node {
+ getClubList(list: Array | undefined) {
+ if (!list) {
+ return null;
+ }
+
list.sort(this.sortClubList);
return (
{
navigation.navigate('club-information', {clubId: id});
}
- render(): React.Node {
+ render() {
const {navigation} = this.props;
return (