Application Android et IOS pour l'amicale des élèves https://play.google.com/store/apps/details?id=fr.amicaleinsat.application
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.

ErrorView.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // @flow
  2. import * as React from 'react';
  3. import {Button, Subheading, withTheme} from 'react-native-paper';
  4. import {StyleSheet, View} from 'react-native';
  5. import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
  6. import i18n from 'i18n-js';
  7. import * as Animatable from 'react-native-animatable';
  8. import {StackNavigationProp} from '@react-navigation/stack';
  9. import {ERROR_TYPE} from '../../utils/WebData';
  10. import type {CustomThemeType} from '../../managers/ThemeManager';
  11. type PropsType = {
  12. navigation: StackNavigationProp,
  13. theme: CustomThemeType,
  14. route: {name: string},
  15. onRefresh?: () => void,
  16. errorCode?: number,
  17. icon?: string,
  18. message?: string,
  19. showRetryButton?: boolean,
  20. };
  21. const styles = StyleSheet.create({
  22. outer: {
  23. height: '100%',
  24. },
  25. inner: {
  26. marginTop: 'auto',
  27. marginBottom: 'auto',
  28. },
  29. iconContainer: {
  30. marginLeft: 'auto',
  31. marginRight: 'auto',
  32. marginBottom: 20,
  33. },
  34. subheading: {
  35. textAlign: 'center',
  36. paddingHorizontal: 20,
  37. },
  38. button: {
  39. marginTop: 10,
  40. marginLeft: 'auto',
  41. marginRight: 'auto',
  42. },
  43. });
  44. class ErrorView extends React.PureComponent<PropsType> {
  45. static defaultProps = {
  46. onRefresh: () => {},
  47. errorCode: 0,
  48. icon: '',
  49. message: '',
  50. showRetryButton: true,
  51. };
  52. message: string;
  53. icon: string;
  54. showLoginButton: boolean;
  55. constructor(props: PropsType) {
  56. super(props);
  57. this.icon = '';
  58. }
  59. getRetryButton(): React.Node {
  60. const {props} = this;
  61. return (
  62. <Button
  63. mode="contained"
  64. icon="refresh"
  65. onPress={props.onRefresh}
  66. style={styles.button}>
  67. {i18n.t('general.retry')}
  68. </Button>
  69. );
  70. }
  71. getLoginButton(): React.Node {
  72. return (
  73. <Button
  74. mode="contained"
  75. icon="login"
  76. onPress={this.goToLogin}
  77. style={styles.button}>
  78. {i18n.t('screens.login.title')}
  79. </Button>
  80. );
  81. }
  82. goToLogin = () => {
  83. const {props} = this;
  84. props.navigation.navigate('login', {
  85. screen: 'login',
  86. params: {nextScreen: props.route.name},
  87. });
  88. };
  89. generateMessage() {
  90. const {props} = this;
  91. this.showLoginButton = false;
  92. if (props.errorCode !== 0) {
  93. switch (props.errorCode) {
  94. case ERROR_TYPE.BAD_CREDENTIALS:
  95. this.message = i18n.t('errors.badCredentials');
  96. this.icon = 'account-alert-outline';
  97. break;
  98. case ERROR_TYPE.BAD_TOKEN:
  99. this.message = i18n.t('errors.badToken');
  100. this.icon = 'account-alert-outline';
  101. this.showLoginButton = true;
  102. break;
  103. case ERROR_TYPE.NO_CONSENT:
  104. this.message = i18n.t('errors.noConsent');
  105. this.icon = 'account-remove-outline';
  106. break;
  107. case ERROR_TYPE.TOKEN_SAVE:
  108. this.message = i18n.t('errors.tokenSave');
  109. this.icon = 'alert-circle-outline';
  110. break;
  111. case ERROR_TYPE.BAD_INPUT:
  112. this.message = i18n.t('errors.badInput');
  113. this.icon = 'alert-circle-outline';
  114. break;
  115. case ERROR_TYPE.FORBIDDEN:
  116. this.message = i18n.t('errors.forbidden');
  117. this.icon = 'lock';
  118. break;
  119. case ERROR_TYPE.CONNECTION_ERROR:
  120. this.message = i18n.t('errors.connectionError');
  121. this.icon = 'access-point-network-off';
  122. break;
  123. case ERROR_TYPE.SERVER_ERROR:
  124. this.message = i18n.t('errors.serverError');
  125. this.icon = 'server-network-off';
  126. break;
  127. default:
  128. this.message = i18n.t('errors.unknown');
  129. this.icon = 'alert-circle-outline';
  130. break;
  131. }
  132. this.message += `\n\nCode ${
  133. props.errorCode != null ? props.errorCode : -1
  134. }`;
  135. } else {
  136. this.message = props.message != null ? props.message : '';
  137. this.icon = props.icon != null ? props.icon : '';
  138. }
  139. }
  140. render(): React.Node {
  141. const {props} = this;
  142. this.generateMessage();
  143. let button;
  144. if (this.showLoginButton) button = this.getLoginButton();
  145. else if (props.showRetryButton) button = this.getRetryButton();
  146. else button = null;
  147. return (
  148. <Animatable.View
  149. style={{
  150. ...styles.outer,
  151. backgroundColor: props.theme.colors.background,
  152. }}
  153. animation="zoomIn"
  154. duration={200}
  155. useNativeDriver>
  156. <View style={styles.inner}>
  157. <View style={styles.iconContainer}>
  158. <MaterialCommunityIcons
  159. // $FlowFixMe
  160. name={this.icon}
  161. size={150}
  162. color={props.theme.colors.textDisabled}
  163. />
  164. </View>
  165. <Subheading
  166. style={{
  167. ...styles.subheading,
  168. color: props.theme.colors.textDisabled,
  169. }}>
  170. {this.message}
  171. </Subheading>
  172. {button}
  173. </View>
  174. </Animatable.View>
  175. );
  176. }
  177. }
  178. export default withTheme(ErrorView);