bw-expo-app/components/profile/profile-error-state.tsx

107 lines
2.7 KiB
TypeScript

import React from 'react';
import { View, TouchableOpacity } from 'react-native';
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import { ThemedText } from '@/components/themed-text';
import { useColorScheme } from '@/hooks/use-color-scheme';
export function ProfileErrorState({ onRetry }: { onRetry: () => void }) {
const colorScheme = useColorScheme();
const palette = colorScheme === 'dark' ? darkPalette : lightPalette;
return (
<View style={styles.emptyWrap}>
<View
style={[
styles.emptyGlyph,
{
backgroundColor: palette.glyphBackdrop,
borderColor: palette.border,
},
]}
>
<MaterialIcons name="error-outline" size={40} color={palette.textSecondary} />
</View>
<ThemedText style={[styles.emptyTitle, { color: palette.textPrimary }]}>Failed to load</ThemedText>
<ThemedText style={[styles.emptySubtitle, { color: palette.textSecondary }]}>
There was an error loading your content
</ThemedText>
<TouchableOpacity
activeOpacity={0.9}
onPress={onRetry}
style={[
styles.generateButton,
{
borderColor: palette.accent,
backgroundColor: palette.elevated,
},
]}
>
<MaterialIcons name="refresh" size={18} color={palette.accent} style={styles.generateIcon} />
<ThemedText style={[styles.generateLabel, { color: palette.accent }]}>Retry</ThemedText>
</TouchableOpacity>
</View>
);
}
const darkPalette = {
textPrimary: '#F6F7FA',
textSecondary: '#8E9098',
glyphBackdrop: '#18181D',
border: '#1D1E24',
accent: '#B7FF2F',
elevated: '#101014',
};
const lightPalette = {
textPrimary: '#0F1320',
textSecondary: '#5E6474',
glyphBackdrop: '#E8EBF4',
border: '#E2E5ED',
accent: '#405CFF',
elevated: '#F0F2F8',
};
const styles = {
emptyWrap: {
alignItems: 'center' as const,
paddingTop: 32,
},
emptyGlyph: {
width: 112,
height: 112,
borderRadius: 28,
borderWidth: 1,
alignItems: 'center' as const,
justifyContent: 'center' as const,
marginBottom: 24,
},
emptyTitle: {
fontSize: 18,
fontWeight: '700' as const,
marginBottom: 6,
},
emptySubtitle: {
fontSize: 14,
lineHeight: 20,
textAlign: 'center' as const,
marginBottom: 28,
paddingHorizontal: 24,
},
generateButton: {
borderWidth: 1,
borderRadius: 999,
paddingHorizontal: 28,
paddingVertical: 12,
flexDirection: 'row' as const,
alignItems: 'center' as const,
justifyContent: 'center' as const,
},
generateIcon: {
marginRight: 8,
},
generateLabel: {
fontSize: 15,
fontWeight: '700' as const,
},
};