morethanadiagnosis-hub/mobile/app/(tabs)/community.tsx
fullsizemalt 5bc3ca1832 feat: integrate React Query and configure build profiles
- Add React Query provider and client
- Create reusable UI components (Loading, Error, Empty)
- Implement custom hooks with fallback data
- Integrate hooks into Resources and Community screens
- Add pull-to-refresh support
- Configure EAS Build profiles and environment variables
2025-11-18 12:36:52 -08:00

246 lines
6.6 KiB
TypeScript

import React, { useCallback } from 'react';
import {
View,
ScrollView,
Text,
StyleSheet,
SafeAreaView,
TouchableOpacity,
RefreshControl,
} from 'react-native';
import { useCommunity } from '../../hooks/useCommunity';
import { LoadingState } from '../../components/ui/LoadingState';
import { ErrorState } from '../../components/ui/ErrorState';
import { EmptyState } from '../../components/ui/EmptyState';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
header: {
backgroundColor: '#fff',
padding: 16,
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
headerTitle: {
fontSize: 24,
fontWeight: '700',
color: '#000',
marginBottom: 8,
},
section: {
paddingHorizontal: 16,
marginTop: 16,
},
communityCard: {
backgroundColor: '#fff',
borderRadius: 12,
padding: 16,
marginBottom: 12,
},
communityCardHeader: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 12,
},
communityIcon: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#f0f0f0',
justifyContent: 'center',
alignItems: 'center',
marginRight: 12,
},
communityTitle: {
fontSize: 16,
fontWeight: '600',
color: '#000',
},
communityDescription: {
fontSize: 13,
color: '#666',
lineHeight: 20,
marginBottom: 12,
},
memberCount: {
fontSize: 12,
color: '#999',
marginBottom: 10,
},
joinButton: {
backgroundColor: '#0066cc',
paddingVertical: 10,
paddingHorizontal: 16,
borderRadius: 6,
alignItems: 'center',
},
joinButtonText: {
color: '#fff',
fontSize: 13,
fontWeight: '600',
},
sectionTitle: {
fontSize: 18,
fontWeight: '700',
color: '#000',
marginBottom: 12,
},
postCard: {
backgroundColor: '#fff',
borderRadius: 12,
padding: 16,
marginBottom: 12,
},
postHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 8,
},
postAuthor: {
fontWeight: '600',
fontSize: 14,
},
postTime: {
color: '#666',
fontSize: 12,
},
postContent: {
fontSize: 14,
lineHeight: 20,
color: '#333',
marginBottom: 12,
},
postFooter: {
flexDirection: 'row',
borderTopWidth: 1,
borderTopColor: '#f0f0f0',
paddingTop: 12,
},
postStat: {
marginRight: 16,
color: '#666',
fontSize: 12,
},
});
export default function CommunityScreen() {
const { data: posts, isLoading, isError, refetch } = useCommunity();
const onRefresh = useCallback(() => {
refetch();
}, [refetch]);
const communities = [
{
title: 'Support Group',
description: 'Join our growing community of folks navigating chronic illness and cancer. Connect, share, and find strength together.',
members: '2,341 members',
icon: '👥',
},
{
title: 'The Living Room',
description: 'Exclusive support circle for members. A safe space to share your journey, connect with others, and find support.',
members: '856 members',
icon: '🛋️',
},
{
title: 'The Journal',
description: 'Read inspiring stories from our community members as they navigate their journeys. Share your own story.',
members: '1,203 stories',
icon: '📖',
},
{
title: 'Podcast Community',
description: 'Discuss episodes of our podcast and connect with listeners who share your experiences.',
members: '432 members',
icon: '🎙️',
},
];
if (isLoading) {
return <LoadingState message="Loading community..." />;
}
if (isError) {
return <ErrorState message="Failed to load community content" onRetry={refetch} />;
}
return (
<SafeAreaView style={styles.container}>
<ScrollView
showsVerticalScrollIndicator={false}
refreshControl={
<RefreshControl refreshing={isLoading} onRefresh={onRefresh} />
}
>
<View style={styles.header}>
<Text style={styles.headerTitle}>Community</Text>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Join Our Communities</Text>
</View>
{communities.map((community, index) => (
<View key={index} style={styles.section}>
<View style={styles.communityCard}>
<View style={styles.communityCardHeader}>
<View style={styles.communityIcon}>
<Text style={{ fontSize: 20 }}>{community.icon}</Text>
</View>
<Text style={styles.communityTitle}>{community.title}</Text>
</View>
<Text style={styles.communityDescription}>{community.description}</Text>
<Text style={styles.memberCount}>{community.members}</Text>
<TouchableOpacity style={styles.joinButton}>
<Text style={styles.joinButtonText}>Join Community</Text>
</TouchableOpacity>
</View>
</View>
))}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Recent Activity</Text>
</View>
{!posts || posts.length === 0 ? (
<View style={styles.section}>
<EmptyState title="No Recent Activity" message="Be the first to post!" />
</View>
) : (
posts.map((post) => (
<View key={post.id} style={styles.section}>
<View style={styles.postCard}>
<View style={styles.postHeader}>
<Text style={styles.postAuthor}>{post.author}</Text>
<Text style={styles.postTime}>{post.timestamp}</Text>
</View>
<Text style={styles.postContent}>{post.content}</Text>
<View style={styles.postFooter}>
<Text style={styles.postStat}>{post.likes} Likes</Text>
<Text style={styles.postStat}>{post.comments} Comments</Text>
</View>
</View>
</View>
))
)}
<View style={[styles.section, { marginBottom: 40 }]}>
<View style={styles.communityCard}>
<Text style={styles.communityTitle}>Community Guidelines</Text>
<Text style={[styles.communityDescription, { marginTop: 8 }]}>
Be respectful and supportive{'\n'}
Share your authentic story{'\n'}
Respect others' privacy{'\n'}
• No medical advice{'\n'}
Check in, not out
</Text>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
}