1- import React from 'react' ;
2- import { useUser } from '@/contexts/UserContext ' ;
3- import { SafeAreaView , View , Text , StyleSheet , ScrollView , TouchableOpacity , Image , Dimensions } from 'react-native' ;
4- import { LineChart , PieChart } from 'react-native-chart-kit' ;
1+ import React , { useMemo , useState } from 'react' ;
2+ import { useAuth } from '@/contexts/AuthContext ' ;
3+ import { SafeAreaView , View , Text , StyleSheet , ScrollView , TouchableOpacity , Image , Dimensions , } from 'react-native' ;
4+ import { LineChart } from 'react-native-chart-kit' ;
55import { router } from 'expo-router' ;
66import { usePersonalBests } from "@/hooks/usePersonalBests" ;
7+ import { Dialog } from '@/components/ui/Dialog' ;
8+ import { Button } from '@/components/ui/Button' ;
79
810const { width } = Dimensions . get ( 'window' ) ;
911//console.log(" 1 HomeScreen about to be rendered rendered");
1012const HomeScreen = ( ) => {
1113 //console.log("2 HomeScreen rendered");
12- // TODO: Replace with real data
13- const bmiValue = '20.1' ;
14- const user = useUser ( ) ;
14+ const { user } = useAuth ( ) ;
1515 if ( ! user ) {
1616 console . warn ( "User context is undefined" ) ;
1717 return null ;
1818 }
19- const { name } = user ;
20- const heartRateData = [ 60 , 62 , 65 , 70 , 75 , 78 , 80 , 82 , 79 , 76 ] ;
21- const waterIntake = '4L' ;
22- const sleepHours = '8h 20m' ;
23- const caloriesBurnt = 760 ;
24- const caloriesLeft = 230 ;
19+ // 1) Calculate BMI (kg / m²) whenever height or weight change
20+ // - height is in cm -> convert to meters by dividing by 100
21+ // - weight is in kg, so we can directly use it in the formula
22+ const bmiValue = useMemo ( ( ) => {
23+ if ( ! user . height || ! user . weight ) return null ;
24+ const heightMeters = user . height / 100 ;
25+ if ( heightMeters <= 0 ) return null ;
26+ const raw = user . weight / ( heightMeters * heightMeters ) ;
27+ return Number ( raw . toFixed ( 1 ) ) ;
28+ } , [ user . height , user . weight ] ) ;
29+
30+ // 2) Derive the status string based on BMI ranges
31+ const bmiStatus = useMemo ( ( ) => {
32+ if ( bmiValue === null ) return '—' ;
33+ if ( bmiValue < 18.5 ) return 'Underweight' ;
34+ if ( bmiValue < 25 ) return 'Normal Weight' ;
35+ if ( bmiValue < 30 ) return 'Overweight' ;
36+ if ( bmiValue < 35 ) return 'Obesity Class 1' ;
37+ if ( bmiValue < 40 ) return 'Obesity Class 2' ;
38+ return 'Obesity Class 3' ;
39+ } , [ bmiValue ] ) ;
40+
41+ const [ showBmiDialog , setShowBmiDialog ] = useState ( false ) ;
42+
2543 const workoutProgressData = [ 20 , 40 , 30 , 60 , 90 , 80 , 70 ] ;
2644 const workoutDays = [ 'Sun' , 'Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' , 'Sat' ] ;
2745 const latestWorkouts = [
@@ -41,39 +59,24 @@ const HomeScreen = () => {
4159 { /* Header */ }
4260 < View style = { styles . header } >
4361 < Text style = { styles . welcomeText } > Welcome Back,</ Text >
44- < Text style = { styles . userName } > { name } </ Text >
62+ < Text style = { styles . userName } > { user . full_name } </ Text >
4563 < TouchableOpacity style = { styles . notificationBtn } onPress = { ( ) => router . push ( '/notification' ) } >
4664 < Image source = { require ( '../assets/images/bell.png' ) } style = { styles . bellIcon } />
4765 </ TouchableOpacity >
4866 </ View >
4967
50- { /* BMI Card */ }
68+ { /* ===== BMI Card ===== */ }
5169 < View style = { styles . bmiCard } >
5270 < View style = { styles . bmiInfo } >
5371 < Text style = { styles . bmiLabel } > BMI (Body Mass Index)</ Text >
54- < Text style = { styles . bmiStatus } > You have a normal weight </ Text >
55- < TouchableOpacity style = { styles . viewMoreBtn } onPress = { ( ) => alert ( 'BMI screen not yet implemented' ) } >
72+ < Text style = { styles . bmiStatus } > { bmiStatus } </ Text >
73+ < TouchableOpacity style = { styles . viewMoreBtn } onPress = { ( ) => setShowBmiDialog ( true ) } >
5674 < Text style = { styles . viewMoreText } > View More</ Text >
5775 </ TouchableOpacity >
5876 </ View >
59- < PieChart
60- data = { [
61- { name : 'BMI' , population : parseFloat ( bmiValue ) , color : '#A3C9FD' , legendFontColor : '#7F7F7F' , legendFontSize : 15 } ,
62- { name : 'Other' , population : 30 - parseFloat ( bmiValue ) , color : '#E5EFFF' , legendFontColor : '#7F7F7F' , legendFontSize : 15 } ,
63- ] }
64- width = { 100 }
65- height = { 100 }
66- chartConfig = { {
67- color : ( opacity = 1 ) => `rgba(163, 201, 253, ${ opacity } )` ,
68- } }
69- accessor = { 'population' }
70- backgroundColor = { 'transparent' }
71- paddingLeft = { '0' }
72- hasLegend = { false }
73- center = { [ 0 , 0 ] }
74- />
77+
7578 < View style = { styles . bmiOverlay } >
76- < Text style = { styles . bmiValue } > { bmiValue } </ Text >
79+ < Text style = { styles . bmiValue } > { bmiValue !== null ? bmiValue . toString ( ) : '-' } </ Text >
7780 </ View >
7881 </ View >
7982
@@ -85,73 +88,6 @@ const HomeScreen = () => {
8588 </ TouchableOpacity >
8689 </ View >
8790
88- { /* Activity Status */ }
89- < Text style = { styles . sectionTitle } > Activity Status</ Text >
90- < View style = { styles . activityCard } >
91- < Text style = { styles . activityLabel } > Heart Rate</ Text >
92- < Text style = { styles . activityValue } > 78 BPM</ Text >
93- < LineChart
94- data = { {
95- labels : [ ] ,
96- datasets : [
97- {
98- data : heartRateData ,
99- color : ( ) => '#91D5A1' ,
100- strokeWidth : 2 ,
101- } ,
102- ] ,
103- } }
104- width = { width - 64 }
105- height = { 100 }
106- chartConfig = { {
107- backgroundGradientFrom : '#fff' ,
108- backgroundGradientTo : '#fff' ,
109- color : ( ) => '#91D5A1' ,
110- strokeWidth : 2 ,
111- } }
112- bezier
113- style = { styles . lineChart }
114- />
115- < View style = { styles . timestampBadge } >
116- < Text style = { styles . timestampText } > 3 mins ago</ Text >
117- </ View >
118- </ View >
119-
120- { /* Stats Grid */ }
121- < View style = { styles . statsGrid } >
122- < View style = { styles . statsCard } >
123- < Text style = { styles . statsLabel } > Water Intake</ Text >
124- < Text style = { styles . statsValue } > { waterIntake } </ Text >
125- </ View >
126- < View style = { styles . statsCard } >
127- < Text style = { styles . statsLabel } > Sleep</ Text >
128- < Text style = { styles . statsValue } > { sleepHours } </ Text >
129- </ View >
130- < View style = { styles . statsCardSmall } >
131- < Text style = { styles . statsLabel } > Calories</ Text >
132- < Text style = { styles . statsValue } > { caloriesBurnt } kCal</ Text >
133- < PieChart
134- data = { [
135- { name : 'Burnt' , population : caloriesBurnt , color : '#FFC069' , legendFontColor : '#7F7F7F' , legendFontSize : 15 } ,
136- { name : 'Left' , population : caloriesLeft , color : '#FFECCE' , legendFontColor : '#7F7F7F' , legendFontSize : 15 } ,
137- ] }
138- width = { 80 }
139- height = { 80 }
140- chartConfig = { {
141- color : ( opacity = 1 ) => `rgba(255, 192, 105, ${ opacity } )` ,
142- } }
143- accessor = { 'population' }
144- backgroundColor = { 'transparent' }
145- paddingLeft = { '0' }
146- hasLegend = { false }
147- center = { [ 0 , 0 ] }
148- />
149- < View style = { styles . calOverlay } >
150- < Text style = { styles . calOverlayText } > { caloriesLeft } kCal</ Text >
151- </ View >
152- </ View >
153- </ View >
154-
15591 { /* Workout Progress */ }
15692 < View style = { styles . progressSection } >
15793 < View style = { styles . progressHeader } >
@@ -238,6 +174,28 @@ const HomeScreen = () => {
238174
239175
240176 </ ScrollView >
177+ { /* ─── BMI Disclaimer Dialog ─── */ }
178+ < Dialog
179+ isOpen = { showBmiDialog }
180+ onClose = { ( ) => setShowBmiDialog ( false ) }
181+ title = "BMI Disclaimer"
182+ size = "sm"
183+ footer = {
184+ < View style = { styles . footer } >
185+ < Button
186+ title = "OK"
187+ onPress = { ( ) => setShowBmiDialog ( false ) }
188+ style = { styles . okButton }
189+ />
190+ </ View >
191+ }
192+ >
193+ < Text style = { styles . bodyText } >
194+ BMI is a screening tool and should not be used as a definitive diagnosis of health problems.
195+ It does not take into account factors such as muscle mass, body composition, or age.
196+ It is recommended to consult with a healthcare professional for personalized advice on weight management and health.
197+ </ Text >
198+ </ Dialog >
241199 </ SafeAreaView >
242200 ) ;
243201} ;
@@ -266,6 +224,9 @@ const styles = StyleSheet.create({
266224 bmiPie : { height : 100 , width : 100 , flex : 1 } ,
267225 bmiOverlay : { position : 'absolute' , right : 32 , top : 32 , alignItems : 'center' } ,
268226 bmiValue : { fontSize : 18 , fontWeight : 'bold' , color : '#333' } ,
227+ footer : { flexDirection : 'row' , justifyContent : 'flex-end' } ,
228+ okButton : { backgroundColor : '#70A1FF' } ,
229+ bodyText : { fontSize : 14 , color : '#333' , lineHeight : 20 } ,
269230 targetCard : { flexDirection : 'row' , backgroundColor : '#F5F8FF' , borderRadius : 16 , padding : 16 , alignItems : 'center' , marginBottom : 24 } ,
270231 targetText : { fontSize : 16 , color : '#333' } ,
271232 checkBtn : { marginLeft : 'auto' , backgroundColor : '#A3C9FD' , borderRadius : 12 , paddingVertical : 6 , paddingHorizontal : 12 } ,
0 commit comments