| import React from 'react'; | |
| import { StyleSheet, View } from 'react-native'; | |
| import { useTheme, Text, Button, IconButton, Surface } from 'react-native-paper'; | |
| export interface ErrorStateProps { | |
| /** Error message to display */ | |
| message?: string; | |
| /** Callback invoked when the retry button is pressed */ | |
| onRetry?: () => void; | |
| } | |
| /** | |
| * Reusable error state with a warning icon, message, and optional | |
| * retry button. Useful for fetch-failure fallbacks throughout the app. | |
| */ | |
| export function ErrorState({ message, onRetry }: ErrorStateProps) { | |
| const theme = useTheme(); | |
| return ( | |
| <Surface | |
| style={[styles.container, { backgroundColor: theme.colors.surface }]} | |
| elevation={0} | |
| > | |
| <View style={styles.content}> | |
| <IconButton | |
| icon="alert-circle-outline" | |
| size={56} | |
| iconColor={theme.colors.error} | |
| style={styles.icon} | |
| disabled | |
| /> | |
| <Text | |
| variant="titleMedium" | |
| style={[styles.title, { color: theme.colors.error }]} | |
| > | |
| Something went wrong | |
| </Text> | |
| {message ? ( | |
| <Text | |
| variant="bodyMedium" | |
| style={[styles.message, { color: theme.colors.onSurfaceVariant }]} | |
| > | |
| {message} | |
| </Text> | |
| ) : null} | |
| {onRetry ? ( | |
| <Button | |
| mode="contained" | |
| onPress={onRetry} | |
| style={styles.retryButton} | |
| icon="refresh" | |
| > | |
| Try Again | |
| </Button> | |
| ) : null} | |
| </View> | |
| </Surface> | |
| ); | |
| } | |
| const styles = StyleSheet.create({ | |
| container: { | |
| flex: 1, | |
| borderRadius: 12, | |
| }, | |
| content: { | |
| alignItems: 'center', | |
| justifyContent: 'center', | |
| padding: 24, | |
| gap: 8, | |
| }, | |
| icon: { | |
| margin: 0, | |
| }, | |
| title: { | |
| textAlign: 'center', | |
| }, | |
| message: { | |
| textAlign: 'center', | |
| maxWidth: 280, | |
| }, | |
| retryButton: { | |
| marginTop: 8, | |
| }, | |
| }); | |