diff --git a/frontend/src/navigations/TabBar.tsx b/frontend/src/navigations/TabBar.tsx index 0de89a547..b3da1e990 100644 --- a/frontend/src/navigations/TabBar.tsx +++ b/frontend/src/navigations/TabBar.tsx @@ -20,6 +20,7 @@ const TAB_CONFIG: Record< Home: {active: 'home', inactive: 'home-outline', label: 'Home'}, Podcasts: {active: 'headphones', inactive: 'headphones', label: 'Podcasts'}, Chatbot: {active: 'robot', inactive: 'robot-outline', label: 'AI'}, + Wellness: {active: 'heart', inactive: 'heart-outline', label: 'Wellness'}, Profile: {active: 'account-circle', inactive: 'account-circle-outline', label: 'Profile'}, About: {active: 'information', inactive: 'information-outline', label: 'About'}, }; diff --git a/frontend/src/navigations/TabNavigation.tsx b/frontend/src/navigations/TabNavigation.tsx index 14484056a..b2bbc3b03 100644 --- a/frontend/src/navigations/TabNavigation.tsx +++ b/frontend/src/navigations/TabNavigation.tsx @@ -16,6 +16,7 @@ import PersonaLobbyScreen from '../screens/PersonaLobbyScreen'; import AboutScreen from '../screens/AboutPage'; import {useSelector} from 'react-redux'; import GuestPlaceholderScreen from '../components/GuestPlaceholderScreen'; +import WellnessDashboardScreen from '../screens/WellnessDashboardScreen'; const Tab = createBottomTabNavigator(); @@ -100,6 +101,22 @@ const TabNavigation = () => { ), })} /> + { + const isDarkMode = useColorScheme() === 'dark'; + const bottomBarHeight = useBottomTabBarHeight(); + const screenWidth = Dimensions.get('window').width; + + // Static placeholder data as requested + const wellnessScore = 85; + const riskLevel = 'Low'; // Low, Medium, High + + const metrics = [ + { + id: 'steps', + title: 'Steps', + value: '8,450', + target: '/ 10,000 steps', + progress: 0.845, + icon: 'walk', + color: '#4CAF50', + description: '84% of daily goal' + }, + { + id: 'sleep', + title: 'Sleep', + value: '7.5 hrs', + target: '/ 8.0 hrs', + progress: 0.937, + icon: 'moon', + color: '#9C27B0', + description: 'Good quality sleep' + }, + { + id: 'heartRate', + title: 'Heart Rate', + value: '72 bpm', + target: 'Resting avg', + progress: 0.72, + icon: 'heart', + color: '#F44336', + description: 'Normal resting zone' + }, + { + id: 'hydration', + title: 'Hydration', + value: '1.8L', + target: '/ 2.5L total', + progress: 0.72, + icon: 'water', + color: '#2196F3', + description: '0.7L remaining' + } + ]; + + const recommendations = [ + { + id: '1', + type: 'warning', + text: 'Increase water intake: You are still 0.7L away from your daily hydration target.', + icon: 'water-outline', + iconColor: '#2196F3' + }, + { + id: '2', + type: 'success', + text: 'Great sleep quality last night! You achieved deep rest cycles for 7.5 hours.', + icon: 'checkmark-circle-outline', + iconColor: '#4CAF50' + }, + { + id: '3', + type: 'info', + text: 'Keep up the step activity. You are close to hitting your 10,000 daily steps goal.', + icon: 'trending-up-outline', + iconColor: '#FF9800' + } + ]; + + // Chart data for wellness trend (Mon - Sun) + const chartData = { + labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + datasets: [ + { + data: [78, 80, 82, 81, 85, 84, 85], + color: (opacity = 1) => `rgba(0, 191, 255, ${opacity})`, + strokeWidth: 3 + } + ], + legend: ['Wellness Trend'] + }; + + const getRiskBadgeColor = (risk: string) => { + switch (risk.toLowerCase()) { + case 'low': return '#E8F5E9'; + case 'medium': return '#FFF8E1'; + case 'high': return '#FFEBEE'; + default: return '#ECEFF1'; + } + }; + + const getRiskTextColor = (risk: string) => { + switch (risk.toLowerCase()) { + case 'low': return '#2E7D32'; + case 'medium': return '#F57F17'; + case 'high': return '#C62828'; + default: return '#37474F'; + } + }; + + return ( + + + {/* Header Greeting */} + + + Wellness Dashboard + + + Track your vital metrics and customized health score. + + + + {/* Score & Risk Badge Section */} + + + + + Overall Health Score + + + Your score is calculated based on sleep, steps, and hydration trends. + + + + + + {riskLevel} Risk + + + + + + {/* Circular Ring Presentation */} + + + {wellnessScore} + + + /100 + + + + + + {/* Metrics Grid */} + + Today's Metrics + + + {metrics.map((item) => ( + + + + {item.title} + + + + + + + {item.value} + + + {item.target} + + + + {/* Progress Line */} + + + + + + {item.description} + + + ))} + + + {/* Line Chart Section */} + + Weekly Trend + + + isDarkMode ? `rgba(255, 255, 255, ${opacity})` : `rgba(15, 82, 186, ${opacity})`, + labelColor: (opacity = 1) => isDarkMode ? `rgba(176, 196, 222, ${opacity})` : `rgba(102, 102, 102, ${opacity})`, + propsForDots: { + r: '4', + strokeWidth: '2', + stroke: PRIMARY_COLOR + }, + propsForBackgroundLines: { + stroke: isDarkMode ? '#334EBC' : '#E5E7EB', + strokeDasharray: '' + } + }} + bezier + style={{ + marginVertical: 4, + borderRadius: 16 + }} + /> + + + {/* Actionable Recommendations */} + + Insights & Recommendations + + + {recommendations.map((rec) => ( + + + + + {rec.text} + + + + ))} + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1 + }, + scoreCircle: { + width: 80, + height: 80, + borderRadius: 40, + borderWidth: 6, + borderColor: PRIMARY_COLOR, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'rgba(0, 191, 255, 0.08)' + }, + progressBarBackground: { + height: 6, + width: '100%', + backgroundColor: '#ECEFF1', + borderRadius: 3, + marginTop: 8, + overflow: 'hidden' + }, + progressBarFill: { + height: '100%', + borderRadius: 3 + } +}); + +export default WellnessDashboardScreen; diff --git a/frontend/src/type.ts b/frontend/src/type.ts index 4d1165e25..6c8d72bee 100644 --- a/frontend/src/type.ts +++ b/frontend/src/type.ts @@ -180,6 +180,7 @@ export type TabParamList = { Profile: undefined; Chatbot: undefined; About: undefined; + Wellness: undefined; }; export type SplashScreenProp =