Application Android et IOS pour l'amicale des élèves
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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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 {CustomTheme} from '../../managers/ThemeManager';
  11. type PropsType = {
  12. navigation: StackNavigationProp,
  13. theme: CustomTheme,
  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: (): void => null,
  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 ${props.errorCode}`;
  133. } else {
  134. this.message = props.message;
  135. this.icon = props.icon;
  136. }
  137. }
  138. render(): React.Node {
  139. const {props} = this;
  140. this.generateMessage();
  141. let button;
  142. if (this.showLoginButton) button = this.getLoginButton();
  143. else if (props.showRetryButton) button = this.getRetryButton();
  144. else button = null;
  145. return (
  146. <Animatable.View
  147. style={{
  148. ...styles.outer,
  149. backgroundColor: props.theme.colors.background,
  150. }}
  151. animation="zoomIn"
  152. duration={200}
  153. useNativeDriver>
  154. <View style={styles.inner}>
  155. <View style={styles.iconContainer}>
  156. <MaterialCommunityIcons
  157. name={this.icon}
  158. size={150}
  159. color={props.theme.colors.textDisabled}
  160. />
  161. </View>
  162. <Subheading
  163. style={{
  164. ...styles.subheading,
  165. color: props.theme.colors.textDisabled,
  166. }}>
  167. {this.message}
  168. </Subheading>
  169. {button}
  170. </View>
  171. </Animatable.View>
  172. );
  173. }
  174. }
  175. export default withTheme(ErrorView);