morethanadiagnosis-hub/mobile/app/(tabs)/resources.tsx
2025-11-19 09:42:02 -08:00

143 lines
4.3 KiB
TypeScript

import React, { useCallback } from 'react';
import {
View,
ScrollView,
Text,
StyleSheet,
SafeAreaView,
TouchableOpacity,
RefreshControl,
StatusBar,
} from 'react-native';
import { useResources } from '../../hooks/useResources';
import { LoadingState } from '../../components/ui/LoadingState';
import { ErrorState } from '../../components/ui/ErrorState';
import { EmptyState } from '../../components/ui/EmptyState';
import { Theme } from '../../constants/Theme';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Theme.colors.background,
},
header: {
backgroundColor: Theme.colors.surface,
padding: Theme.spacing.l,
borderBottomWidth: 1,
borderBottomColor: Theme.colors.border,
},
headerTitle: {
...Theme.typography.heading,
color: Theme.colors.primary,
marginBottom: Theme.spacing.s,
},
headerDescription: {
...Theme.typography.body,
color: Theme.colors.textMuted,
},
section: {
paddingHorizontal: Theme.spacing.m,
marginTop: Theme.spacing.l,
},
sectionTitle: {
...Theme.typography.subheading,
color: Theme.colors.text,
marginBottom: Theme.spacing.m,
},
resourceCard: {
backgroundColor: Theme.colors.surface,
borderRadius: Theme.borderRadius.m,
padding: Theme.spacing.m,
marginBottom: Theme.spacing.m,
borderLeftWidth: 4,
borderLeftColor: Theme.colors.primary,
...Theme.shadows.small,
},
resourceTitle: {
...Theme.typography.subheading,
fontSize: 16,
color: Theme.colors.text,
marginBottom: Theme.spacing.xs,
},
resourceDescription: {
...Theme.typography.body,
fontSize: 14,
color: Theme.colors.textMuted,
marginBottom: Theme.spacing.m,
},
resourceLink: {
paddingVertical: Theme.spacing.s,
paddingHorizontal: Theme.spacing.m,
backgroundColor: Theme.colors.secondaryLight,
borderRadius: Theme.borderRadius.s,
alignSelf: 'flex-start',
},
resourceLinkText: {
color: Theme.colors.primaryDark,
fontSize: 12,
fontWeight: '600',
},
});
export default function ResourcesScreen() {
const { data: resources, isLoading, isError, refetch } = useResources();
const onRefresh = useCallback(() => {
refetch();
}, [refetch]);
if (isLoading) {
return <LoadingState message="Loading resources..." />;
}
if (isError) {
return <ErrorState message="Failed to load resources" onRetry={refetch} />;
}
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" backgroundColor={Theme.colors.background} />
<ScrollView
showsVerticalScrollIndicator={false}
refreshControl={
<RefreshControl
refreshing={isLoading}
onRefresh={onRefresh}
tintColor={Theme.colors.primary}
colors={[Theme.colors.primary]}
/>
}
>
<View style={styles.header}>
<Text style={styles.headerTitle}>Resources</Text>
<Text style={styles.headerDescription}>
We know how scary and overwhelming it can be to receive a diagnosis. We've curated helpful resources to make your journey a little easier.
</Text>
</View>
{!resources || resources.length === 0 ? (
<EmptyState title="No Resources Found" message="Check back later for updates." />
) : (
resources.map((resource) => (
<View key={resource.id} style={styles.section}>
<View style={styles.resourceCard}>
<Text style={styles.resourceTitle}>{resource.title}</Text>
<Text style={styles.resourceDescription}>{resource.description}</Text>
<TouchableOpacity style={styles.resourceLink}>
<Text style={styles.resourceLinkText}>Learn More →</Text>
</TouchableOpacity>
</View>
</View>
))
)}
<View style={[styles.section, { marginBottom: 40 }]}>
<Text style={styles.sectionTitle}>More Coming Soon</Text>
<Text style={{ ...Theme.typography.body, fontSize: 14, color: Theme.colors.textMuted }}>
Be sure to check back often or sign up to receive updates as we're adding new resources all the time!
</Text>
</View>
</ScrollView>
</SafeAreaView>
);
}