feat: initialize React Native mobile app with Expo
Core features implemented: - Expo cross-platform setup (iOS, Android, Web) - Bottom tab navigation (Home, Resources, Community, Profile) - Home screen with all major sections: * Hero section with mission statement * Happy Mail integration * Connect/Support section * Podcast information * Features grid * Wings of Remembrance - Resources screen with curated support materials - Community screen with support groups and circles - Profile screen with user account management - Auth layout structure (login, signup, forgot password) Ready for: - Authentication integration with FastAPI backend - API integration for community features - Database connectivity - Testing on iOS, Android, and Web
This commit is contained in:
parent
229fd6ced4
commit
7eaacb08e1
8 changed files with 17382 additions and 0 deletions
17
mobile/app/(auth)/_layout.tsx
Normal file
17
mobile/app/(auth)/_layout.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Stack } from 'expo-router';
|
||||
|
||||
export default function AuthLayout() {
|
||||
return (
|
||||
<Stack
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
gestureEnabled: false,
|
||||
animationEnabled: true,
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name="login" />
|
||||
<Stack.Screen name="signup" />
|
||||
<Stack.Screen name="forgot-password" />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
69
mobile/app/(tabs)/_layout.tsx
Normal file
69
mobile/app/(tabs)/_layout.tsx
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import { Tabs } from 'expo-router';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
|
||||
export default function TabLayout() {
|
||||
return (
|
||||
<Tabs
|
||||
screenOptions={{
|
||||
headerShown: true,
|
||||
tabBarActiveTintColor: '#0066cc',
|
||||
tabBarInactiveTintColor: '#999',
|
||||
headerStyle: {
|
||||
backgroundColor: '#ffffff',
|
||||
borderBottomColor: '#e0e0e0',
|
||||
borderBottomWidth: 1,
|
||||
},
|
||||
headerTitleStyle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#000',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
options={{
|
||||
title: 'Home',
|
||||
tabBarLabel: 'Home',
|
||||
headerTitle: 'MoreThanADiagnosis',
|
||||
tabBarIcon: ({ color, size }) => (
|
||||
<Ionicons name="home" size={size} color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tabs.Screen
|
||||
name="resources"
|
||||
options={{
|
||||
title: 'Resources',
|
||||
tabBarLabel: 'Resources',
|
||||
tabBarIcon: ({ color, size }) => (
|
||||
<Ionicons name="book" size={size} color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tabs.Screen
|
||||
name="community"
|
||||
options={{
|
||||
title: 'Community',
|
||||
tabBarLabel: 'Community',
|
||||
tabBarIcon: ({ color, size }) => (
|
||||
<Ionicons name="people" size={size} color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tabs.Screen
|
||||
name="profile"
|
||||
options={{
|
||||
title: 'Profile',
|
||||
tabBarLabel: 'Profile',
|
||||
tabBarIcon: ({ color, size }) => (
|
||||
<Ionicons name="person" size={size} color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
161
mobile/app/(tabs)/community.tsx
Normal file
161
mobile/app/(tabs)/community.tsx
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
ScrollView,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
|
||||
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,
|
||||
},
|
||||
});
|
||||
|
||||
export default function CommunityScreen() {
|
||||
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: '🎙️',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<ScrollView showsVerticalScrollIndicator={false}>
|
||||
<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, { 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>
|
||||
);
|
||||
}
|
||||
244
mobile/app/(tabs)/index.tsx
Normal file
244
mobile/app/(tabs)/index.tsx
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
import React, { useState } from 'react';
|
||||
import {
|
||||
View,
|
||||
ScrollView,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
StatusBar,
|
||||
} from 'react-native';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
scrollContent: {
|
||||
paddingBottom: 20,
|
||||
},
|
||||
heroSection: {
|
||||
backgroundColor: '#ffffff',
|
||||
padding: 20,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#e0e0e0',
|
||||
},
|
||||
heroTitle: {
|
||||
fontSize: 28,
|
||||
fontWeight: '700',
|
||||
color: '#000',
|
||||
marginBottom: 10,
|
||||
},
|
||||
heroSubtitle: {
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
lineHeight: 24,
|
||||
marginBottom: 15,
|
||||
},
|
||||
primaryButton: {
|
||||
backgroundColor: '#0066cc',
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 20,
|
||||
borderRadius: 8,
|
||||
alignItems: 'center',
|
||||
},
|
||||
primaryButtonText: {
|
||||
color: '#fff',
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
section: {
|
||||
marginTop: 20,
|
||||
paddingHorizontal: 15,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 20,
|
||||
fontWeight: '700',
|
||||
color: '#000',
|
||||
marginBottom: 12,
|
||||
},
|
||||
sectionDescription: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
lineHeight: 20,
|
||||
marginBottom: 12,
|
||||
},
|
||||
cardContainer: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
marginBottom: 12,
|
||||
borderLeftWidth: 4,
|
||||
borderLeftColor: '#0066cc',
|
||||
},
|
||||
cardTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: '#000',
|
||||
marginBottom: 8,
|
||||
},
|
||||
cardDescription: {
|
||||
fontSize: 13,
|
||||
color: '#666',
|
||||
lineHeight: 18,
|
||||
},
|
||||
featureGrid: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
featureCard: {
|
||||
width: '48%',
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
marginBottom: 12,
|
||||
alignItems: 'center',
|
||||
},
|
||||
featureIcon: {
|
||||
fontSize: 32,
|
||||
marginBottom: 8,
|
||||
},
|
||||
featureTitle: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: '#000',
|
||||
textAlign: 'center',
|
||||
},
|
||||
ctaButton: {
|
||||
backgroundColor: '#0066cc',
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 16,
|
||||
borderRadius: 6,
|
||||
marginTop: 8,
|
||||
},
|
||||
ctaButtonText: {
|
||||
color: '#fff',
|
||||
fontSize: 13,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default function HomeScreen() {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<StatusBar barStyle="dark-content" backgroundColor="#fff" />
|
||||
<ScrollView style={styles.scrollContent} showsVerticalScrollIndicator={false}>
|
||||
{/* Hero Section */}
|
||||
<View style={styles.heroSection}>
|
||||
<Text style={styles.heroTitle}>You are more than a diagnosis.</Text>
|
||||
<Text style={styles.heroSubtitle}>
|
||||
Connecting Through Stories, Thriving Through Community
|
||||
</Text>
|
||||
<TouchableOpacity style={styles.primaryButton}>
|
||||
<Text style={styles.primaryButtonText}>Join Our Community</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Happy Mail Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>💌 Happy Mail</Text>
|
||||
<View style={styles.cardContainer}>
|
||||
<Text style={styles.cardTitle}>Free Joy-Filled Snail Mail</Text>
|
||||
<Text style={styles.cardDescription}>
|
||||
Nerisa sends personalized snail mail to folks navigating cancer and chronic illness.
|
||||
</Text>
|
||||
<Text style={[styles.cardDescription, { marginTop: 8, fontWeight: '600' }]}>
|
||||
Who can receive:
|
||||
</Text>
|
||||
<Text style={[styles.cardDescription, { marginTop: 4 }]}>
|
||||
✓ Cancer diagnosis or treatment{'\n'}
|
||||
✓ Chronic illness or rare disease{'\n'}
|
||||
✓ Medical limbo or recovery
|
||||
</Text>
|
||||
<TouchableOpacity style={styles.ctaButton}>
|
||||
<Text style={styles.ctaButtonText}>Order Happy Mail</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Connect Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>🤝 Connect</Text>
|
||||
<View style={styles.cardContainer}>
|
||||
<Text style={styles.cardTitle}>Safe & Supportive Space</Text>
|
||||
<Text style={styles.cardDescription}>
|
||||
"We're here to create a safe, supportive space where you can connect with others, share your story, and find hope. Cancer and chronic illness can feel so isolating, but together, we're stronger."
|
||||
</Text>
|
||||
<TouchableOpacity style={styles.ctaButton}>
|
||||
<Text style={styles.ctaButtonText}>Learn More</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Podcast Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>🎙️ Podcast</Text>
|
||||
<View style={styles.cardContainer}>
|
||||
<Text style={styles.cardTitle}>More Than A Diagnosis Podcast</Text>
|
||||
<Text style={styles.cardDescription}>
|
||||
Hosted by Jes and Den, who share real stories about life beyond the medical chart.
|
||||
</Text>
|
||||
<TouchableOpacity style={styles.ctaButton}>
|
||||
<Text style={styles.ctaButtonText}>Listen Now</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Features Grid */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>What We Offer</Text>
|
||||
<View style={styles.featureGrid}>
|
||||
<View style={styles.featureCard}>
|
||||
<Text style={styles.featureIcon}>📚</Text>
|
||||
<Text style={styles.featureTitle}>Resources</Text>
|
||||
<Text style={{ fontSize: 12, color: '#999', marginTop: 4 }}>
|
||||
Curated support materials
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.featureCard}>
|
||||
<Text style={styles.featureIcon}>👥</Text>
|
||||
<Text style={styles.featureTitle}>Community</Text>
|
||||
<Text style={{ fontSize: 12, color: '#999', marginTop: 4 }}>
|
||||
Support groups & circles
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.featureCard}>
|
||||
<Text style={styles.featureIcon}>📖</Text>
|
||||
<Text style={styles.featureTitle}>Stories</Text>
|
||||
<Text style={{ fontSize: 12, color: '#999', marginTop: 4 }}>
|
||||
The Journal & experiences
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.featureCard}>
|
||||
<Text style={styles.featureIcon}>🎁</Text>
|
||||
<Text style={styles.featureTitle}>Shop</Text>
|
||||
<Text style={{ fontSize: 12, color: '#999', marginTop: 4 }}>
|
||||
Purpose-driven apparel
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Wings of Remembrance */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>🕊️ Wings of Remembrance</Text>
|
||||
<View style={styles.cardContainer}>
|
||||
<Text style={styles.cardTitle}>Honor Those Who Shaped Us</Text>
|
||||
<Text style={styles.cardDescription}>
|
||||
Share a tribute, memory, or reflection to honor those who shaped our journey.
|
||||
</Text>
|
||||
<TouchableOpacity style={styles.ctaButton}>
|
||||
<Text style={styles.ctaButtonText}>Share Your Tribute</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
260
mobile/app/(tabs)/profile.tsx
Normal file
260
mobile/app/(tabs)/profile.tsx
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
import React, { useState } from 'react';
|
||||
import {
|
||||
View,
|
||||
ScrollView,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
TouchableOpacity,
|
||||
Alert,
|
||||
} from 'react-native';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
profileHeader: {
|
||||
backgroundColor: '#fff',
|
||||
paddingVertical: 24,
|
||||
paddingHorizontal: 16,
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#e0e0e0',
|
||||
},
|
||||
avatar: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 40,
|
||||
backgroundColor: '#0066cc',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
avatarText: {
|
||||
color: '#fff',
|
||||
fontSize: 32,
|
||||
fontWeight: '700',
|
||||
},
|
||||
profileName: {
|
||||
fontSize: 20,
|
||||
fontWeight: '700',
|
||||
color: '#000',
|
||||
marginBottom: 4,
|
||||
},
|
||||
profileStatus: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
},
|
||||
section: {
|
||||
paddingHorizontal: 16,
|
||||
marginTop: 16,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: '#999',
|
||||
textTransform: 'uppercase',
|
||||
marginBottom: 8,
|
||||
},
|
||||
menuItem: {
|
||||
backgroundColor: '#fff',
|
||||
paddingVertical: 14,
|
||||
paddingHorizontal: 16,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#f0f0f0',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
menuItemFirst: {
|
||||
borderTopLeftRadius: 12,
|
||||
borderTopRightRadius: 12,
|
||||
},
|
||||
menuItemLast: {
|
||||
borderBottomLeftRadius: 12,
|
||||
borderBottomRightRadius: 12,
|
||||
borderBottomWidth: 0,
|
||||
},
|
||||
menuIcon: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginRight: 12,
|
||||
},
|
||||
menuLabel: {
|
||||
fontSize: 15,
|
||||
color: '#000',
|
||||
flex: 1,
|
||||
fontWeight: '500',
|
||||
},
|
||||
menuArrow: {
|
||||
color: '#999',
|
||||
},
|
||||
signOutButton: {
|
||||
backgroundColor: '#fff',
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 16,
|
||||
marginTop: 8,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
borderWidth: 1,
|
||||
borderColor: '#ff4444',
|
||||
},
|
||||
signOutText: {
|
||||
color: '#ff4444',
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
|
||||
export default function ProfileScreen() {
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
|
||||
const handleSignOut = () => {
|
||||
Alert.alert('Sign Out', 'Are you sure you want to sign out?', [
|
||||
{ text: 'Cancel', onPress: () => {} },
|
||||
{
|
||||
text: 'Sign Out',
|
||||
onPress: () => {
|
||||
setIsLoggedIn(false);
|
||||
},
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.profileHeader}>
|
||||
<View style={styles.avatar}>
|
||||
<Ionicons name="person" size={40} color="#fff" />
|
||||
</View>
|
||||
<Text style={styles.profileName}>Welcome</Text>
|
||||
<Text style={styles.profileStatus}>Sign in to access your profile</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<TouchableOpacity
|
||||
style={[styles.menuItem, styles.menuItemFirst, styles.menuItemLast]}
|
||||
onPress={() => setIsLoggedIn(true)}
|
||||
>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="log-in" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Sign In</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>About</Text>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemFirst]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="information-circle" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>About Us</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.menuItem}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="shield-checkmark" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Privacy Policy</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemLast]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="document-text" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Terms of Service</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<ScrollView showsVerticalScrollIndicator={false}>
|
||||
<View style={styles.profileHeader}>
|
||||
<View style={styles.avatar}>
|
||||
<Text style={styles.avatarText}>👤</Text>
|
||||
</View>
|
||||
<Text style={styles.profileName}>John Doe</Text>
|
||||
<Text style={styles.profileStatus}>Active Member</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Account</Text>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemFirst]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="person" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Edit Profile</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.menuItem}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="notifications" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Notifications</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemLast]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="lock-closed" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Change Password</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Preferences</Text>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemFirst]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="moon" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Dark Mode</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemLast]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="language" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Language</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Help</Text>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemFirst]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="help-circle" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Help & Support</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={[styles.menuItem, styles.menuItemLast]}>
|
||||
<View style={styles.menuIcon}>
|
||||
<Ionicons name="mail" size={20} color="#0066cc" />
|
||||
</View>
|
||||
<Text style={styles.menuLabel}>Contact Us</Text>
|
||||
<Ionicons name="chevron-forward" size={20} style={styles.menuArrow} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={[styles.section, { marginBottom: 40 }]}>
|
||||
<TouchableOpacity style={styles.signOutButton} onPress={handleSignOut}>
|
||||
<Text style={styles.signOutText}>Sign Out</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
136
mobile/app/(tabs)/resources.tsx
Normal file
136
mobile/app/(tabs)/resources.tsx
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
ScrollView,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
|
||||
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,
|
||||
},
|
||||
headerDescription: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
lineHeight: 20,
|
||||
},
|
||||
section: {
|
||||
paddingHorizontal: 16,
|
||||
marginTop: 16,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: '#000',
|
||||
marginBottom: 12,
|
||||
},
|
||||
resourceCard: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
marginBottom: 12,
|
||||
borderLeftWidth: 4,
|
||||
borderLeftColor: '#0066cc',
|
||||
},
|
||||
resourceTitle: {
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
color: '#000',
|
||||
marginBottom: 6,
|
||||
},
|
||||
resourceDescription: {
|
||||
fontSize: 13,
|
||||
color: '#666',
|
||||
lineHeight: 18,
|
||||
},
|
||||
resourceLink: {
|
||||
marginTop: 10,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 12,
|
||||
backgroundColor: '#f0f0f0',
|
||||
borderRadius: 6,
|
||||
},
|
||||
resourceLinkText: {
|
||||
color: '#0066cc',
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default function ResourcesScreen() {
|
||||
const resources = [
|
||||
{
|
||||
title: 'Financial Support',
|
||||
description: 'Resources for managing medical costs and financial burdens',
|
||||
},
|
||||
{
|
||||
title: 'Mental Health',
|
||||
description: 'Mental health services and counseling resources',
|
||||
},
|
||||
{
|
||||
title: 'Medical Information',
|
||||
description: 'Reliable health information and diagnosis resources',
|
||||
},
|
||||
{
|
||||
title: 'Support Groups',
|
||||
description: 'Connect with others on similar health journeys',
|
||||
},
|
||||
{
|
||||
title: 'Nutrition & Wellness',
|
||||
description: 'Health and wellness resources during treatment',
|
||||
},
|
||||
{
|
||||
title: 'Legal Resources',
|
||||
description: 'Information about health law and patient rights',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<ScrollView showsVerticalScrollIndicator={false}>
|
||||
<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.map((resource, index) => (
|
||||
<View key={index} 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={{ fontSize: 14, color: '#666', lineHeight: 20 }}>
|
||||
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>
|
||||
);
|
||||
}
|
||||
23
mobile/app/_layout.tsx
Normal file
23
mobile/app/_layout.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { Stack } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const unstable_settings = {
|
||||
initialRouteName: '(tabs)',
|
||||
};
|
||||
|
||||
export default function RootLayout() {
|
||||
useEffect(() => {
|
||||
// Setup any global configuration here
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<StatusBar barStyle="dark-content" />
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
16472
mobile/package-lock.json
generated
Normal file
16472
mobile/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue