Skip to content

Commit 2c403b5

Browse files
committed
Displayed Personal Bests Section, Working on Dynamically Updating it with workouts
1 parent d7addee commit 2c403b5

File tree

13 files changed

+1348
-1462
lines changed

13 files changed

+1348
-1462
lines changed

KonditionExpo/app/(tabs)/index.tsx

Lines changed: 2 additions & 350 deletions
Original file line numberDiff line numberDiff line change
@@ -1,350 +1,2 @@
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';
5-
import { router } from 'expo-router';
6-
7-
const { width } = Dimensions.get('window');
8-
9-
const HomeScreen = () => {
10-
// TODO: Replace with real data
11-
const bmiValue = '20.1';
12-
const { name } = useUser();
13-
const heartRateData = [60, 62, 65, 70, 75, 78, 80, 82, 79, 76];
14-
const waterIntake = '4L';
15-
const sleepHours = '8h 20m';
16-
const caloriesBurnt = 760;
17-
const caloriesLeft = 230;
18-
const workoutProgressData = [20, 40, 30, 60, 90, 80, 70];
19-
const workoutDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
20-
const latestWorkouts = [
21-
{ id: '1', type: 'Fullbody Workout', calories: 180, duration: '20 minutes', icon: require('../../assets/images/fullbody.png') },
22-
{ id: '2', type: 'Lowerbody Workout', calories: 200, duration: '30 minutes', icon: require('../../assets/images/lowerbody.png') },
23-
// ... more workouts
24-
];
25-
26-
// If user is not logged in, show landing page
27-
if (!name) {
28-
return (
29-
<ScrollView style={[styles.container]}>
30-
{/* Hero Section */}
31-
<View style={styles.heroContainer}>
32-
<Image
33-
source={require('@/assets/images/icon.png')}
34-
style={styles.logo}
35-
/>
36-
<Text style={styles.appName}>KONDITION</Text>
37-
<Text style={styles.tagline}>Your Personal Fitness Journey Starts Here</Text>
38-
39-
<TouchableOpacity
40-
style={styles.ctaButton}
41-
onPress={() => router.replace('../login')}
42-
>
43-
<Text style={styles.ctaButtonText}>Sign In</Text>
44-
</TouchableOpacity>
45-
</View>
46-
47-
{/* Final CTA */}
48-
<View style={styles.ctaSection}>
49-
<Text style={styles.ctaTitle}>Ready to Start Your Fitness Journey?</Text>
50-
<TouchableOpacity
51-
style={styles.ctaButton}
52-
onPress={() => router.replace('../login')}
53-
>
54-
<Text style={styles.ctaButtonText}>Get Started Now</Text>
55-
</TouchableOpacity>
56-
</View>
57-
</ScrollView>
58-
);
59-
}
60-
61-
return (
62-
<SafeAreaView style={styles.container}>
63-
<ScrollView contentContainerStyle={styles.content}>
64-
{/* Header */}
65-
<View style={styles.header}>
66-
<Text style={styles.welcomeText}>Welcome Back,</Text>
67-
<Text style={styles.userName}>{name}</Text>
68-
<TouchableOpacity style={styles.notificationBtn} onPress={() => router.push('/notification')}>
69-
<Image source={require('../../assets/images/bell.png')} style={styles.bellIcon} />
70-
</TouchableOpacity>
71-
</View>
72-
73-
{/* BMI Card */}
74-
<View style={styles.bmiCard}>
75-
<View style={styles.bmiInfo}>
76-
<Text style={styles.bmiLabel}>BMI (Body Mass Index)</Text>
77-
<Text style={styles.bmiStatus}>You have a normal weight</Text>
78-
<TouchableOpacity style={styles.viewMoreBtn} onPress={() => alert('BMI screen not yet implemented')}>
79-
<Text style={styles.viewMoreText}>View More</Text>
80-
</TouchableOpacity>
81-
</View>
82-
<PieChart
83-
data={[
84-
{ name: 'BMI', population: parseFloat(bmiValue), color: '#A3C9FD', legendFontColor: '#7F7F7F', legendFontSize: 15 },
85-
{ name: 'Other', population: 30 - parseFloat(bmiValue), color: '#E5EFFF', legendFontColor: '#7F7F7F', legendFontSize: 15 },
86-
]}
87-
width={100}
88-
height={100}
89-
chartConfig={{
90-
color: (opacity = 1) => `rgba(163, 201, 253, ${opacity})`,
91-
}}
92-
accessor={'population'}
93-
backgroundColor={'transparent'}
94-
paddingLeft={'0'}
95-
hasLegend={false}
96-
center={[0, 0]}
97-
/>
98-
<View style={styles.bmiOverlay}>
99-
<Text style={styles.bmiValue}>{bmiValue}</Text>
100-
</View>
101-
</View>
102-
103-
{/* Today Target */}
104-
<View style={styles.targetCard}>
105-
<Text style={styles.targetText}>Today Target</Text>
106-
<TouchableOpacity style={styles.checkBtn} onPress={() => alert('Targets screen not yet implemented')}>
107-
<Text style={styles.checkText}>Check</Text>
108-
</TouchableOpacity>
109-
</View>
110-
111-
{/* Activity Status */}
112-
<Text style={styles.sectionTitle}>Activity Status</Text>
113-
<View style={styles.activityCard}>
114-
<Text style={styles.activityLabel}>Heart Rate</Text>
115-
<Text style={styles.activityValue}>78 BPM</Text>
116-
<LineChart
117-
data={{
118-
labels: [],
119-
datasets: [
120-
{
121-
data: heartRateData,
122-
color: () => '#91D5A1',
123-
strokeWidth: 2,
124-
},
125-
],
126-
}}
127-
width={width - 64}
128-
height={100}
129-
chartConfig={{
130-
backgroundGradientFrom: '#fff',
131-
backgroundGradientTo: '#fff',
132-
color: () => '#91D5A1',
133-
strokeWidth: 2,
134-
}}
135-
bezier
136-
style={styles.lineChart}
137-
/>
138-
<View style={styles.timestampBadge}>
139-
<Text style={styles.timestampText}>3 mins ago</Text>
140-
</View>
141-
</View>
142-
143-
{/* Stats Grid */}
144-
<View style={styles.statsGrid}>
145-
<View style={styles.statsCard}>
146-
<Text style={styles.statsLabel}>Water Intake</Text>
147-
<Text style={styles.statsValue}>{waterIntake}</Text>
148-
</View>
149-
<View style={styles.statsCard}>
150-
<Text style={styles.statsLabel}>Sleep</Text>
151-
<Text style={styles.statsValue}>{sleepHours}</Text>
152-
</View>
153-
<View style={styles.statsCardSmall}>
154-
<Text style={styles.statsLabel}>Calories</Text>
155-
<Text style={styles.statsValue}>{caloriesBurnt} kCal</Text>
156-
<PieChart
157-
data={[
158-
{ name: 'Burnt', population: caloriesBurnt, color: '#FFC069', legendFontColor: '#7F7F7F', legendFontSize: 15 },
159-
{ name: 'Left', population: caloriesLeft, color: '#FFECCE', legendFontColor: '#7F7F7F', legendFontSize: 15 },
160-
]}
161-
width={80}
162-
height={80}
163-
chartConfig={{
164-
color: (opacity = 1) => `rgba(255, 192, 105, ${opacity})`,
165-
}}
166-
accessor={'population'}
167-
backgroundColor={'transparent'}
168-
paddingLeft={'0'}
169-
hasLegend={false}
170-
center={[0, 0]}
171-
/>
172-
<View style={styles.calOverlay}>
173-
<Text style={styles.calOverlayText}>{caloriesLeft} kCal</Text>
174-
</View>
175-
</View>
176-
</View>
177-
178-
{/* Workout Progress */}
179-
<View style={styles.progressSection}>
180-
<View style={styles.progressHeader}>
181-
<Text style={styles.sectionTitle}>Workout Progress</Text>
182-
<TouchableOpacity onPress={() => {/* toggle weekly/monthly */}}>
183-
<Text style={styles.periodToggle}>Weekly ▼</Text>
184-
</TouchableOpacity>
185-
</View>
186-
<LineChart
187-
data={{
188-
labels: workoutDays,
189-
datasets: [
190-
{
191-
data: workoutProgressData,
192-
color: () => '#B07FFD',
193-
strokeWidth: 2,
194-
},
195-
],
196-
}}
197-
width={width - 64}
198-
height={100}
199-
chartConfig={{
200-
backgroundGradientFrom: '#fff',
201-
backgroundGradientTo: '#fff',
202-
color: () => '#B07FFD',
203-
strokeWidth: 2,
204-
}}
205-
bezier
206-
style={styles.progressChart}
207-
/>
208-
<View style={styles.daysRow}>
209-
{workoutDays.map(day => (
210-
<Text key={day} style={styles.dayText}>{day}</Text>
211-
))}
212-
</View>
213-
</View>
214-
215-
{/* Latest Workout */}
216-
<View style={styles.latestSection}>
217-
<View style={styles.sectionHeader}>
218-
<Text style={styles.sectionTitle}>Latest Workout</Text>
219-
<TouchableOpacity onPress={() => router.push('/progress')}>
220-
<Text style={styles.seeMore}>See more</Text>
221-
</TouchableOpacity>
222-
</View>
223-
{latestWorkouts.map(w => (
224-
<TouchableOpacity key={w.id} style={styles.workoutItem} onPress={() => alert('Workout Details not yet implemented')}>
225-
<Image source={w.icon} style={styles.workoutIcon} />
226-
<View style={styles.workoutInfo}>
227-
<Text style={styles.workoutType}>{w.type}</Text>
228-
<Text style={styles.workoutMeta}>{w.calories} Calories Burn | {w.duration}</Text>
229-
</View>
230-
<Image source={require('../../assets/images/arrow-right.png')} style={styles.arrowIcon} />
231-
</TouchableOpacity>
232-
))}
233-
</View>
234-
</ScrollView>
235-
</SafeAreaView>
236-
);
237-
};
238-
239-
const styles = StyleSheet.create({
240-
container: { flex: 1, backgroundColor: '#FFFFFF' },
241-
content: { padding: 16, paddingBottom: 80 },
242-
// Landing page styles
243-
heroContainer: {
244-
alignItems: 'center',
245-
paddingTop: 60,
246-
paddingBottom: 40,
247-
paddingHorizontal: 20,
248-
},
249-
logo: {
250-
width: 100,
251-
height: 100,
252-
marginBottom: 16,
253-
},
254-
appName: {
255-
fontSize: 32,
256-
fontWeight: 'bold',
257-
marginBottom: 8,
258-
color: '#333',
259-
},
260-
tagline: {
261-
fontSize: 18,
262-
textAlign: 'center',
263-
marginBottom: 24,
264-
maxWidth: '80%',
265-
color: '#666',
266-
},
267-
ctaButton: {
268-
backgroundColor: '#70A1FF',
269-
paddingVertical: 12,
270-
paddingHorizontal: 32,
271-
borderRadius: 12,
272-
marginBottom: 20,
273-
width: '80%',
274-
alignItems: 'center',
275-
},
276-
ctaButtonText: {
277-
color: '#FFF',
278-
fontSize: 16,
279-
fontWeight: '600',
280-
},
281-
ctaSection: {
282-
padding: 20,
283-
alignItems: 'center',
284-
marginBottom: 40,
285-
},
286-
ctaTitle: {
287-
fontSize: 22,
288-
fontWeight: 'bold',
289-
marginBottom: 20,
290-
textAlign: 'center',
291-
color: '#333',
292-
},
293-
// Dashboard styles
294-
header: { flexDirection: 'row', alignItems: 'center', marginBottom: 24 },
295-
welcomeText: { fontSize: 16, color: '#777' },
296-
userName: { fontSize: 24, fontWeight: 'bold', marginLeft: 8, color: '#333' },
297-
notificationBtn: { marginLeft: 'auto' },
298-
bellIcon: { width: 24, height: 24 },
299-
bmiCard: {
300-
flexDirection: 'row',
301-
backgroundColor: '#E5F1FF',
302-
borderRadius: 20,
303-
padding: 16,
304-
alignItems: 'center',
305-
marginBottom: 24,
306-
},
307-
bmiInfo: { flex: 2 },
308-
bmiLabel: { fontSize: 14, color: '#555' },
309-
bmiStatus: { fontSize: 16, marginVertical: 4, color: '#333' },
310-
viewMoreBtn: { backgroundColor: '#70A1FF', borderRadius: 12, paddingVertical: 6, paddingHorizontal: 12, marginTop: 8, alignSelf: 'flex-start' },
311-
viewMoreText: { color: '#FFF' },
312-
bmiPie: { height: 100, width: 100, flex: 1 },
313-
bmiOverlay: { position: 'absolute', right: 32, top: 32, alignItems: 'center' },
314-
bmiValue: { fontSize: 18, fontWeight: 'bold', color: '#333' },
315-
targetCard: { flexDirection: 'row', backgroundColor: '#F5F8FF', borderRadius: 16, padding: 16, alignItems: 'center', marginBottom: 24 },
316-
targetText: { fontSize: 16, color: '#333' },
317-
checkBtn: { marginLeft: 'auto', backgroundColor: '#A3C9FD', borderRadius: 12, paddingVertical: 6, paddingHorizontal: 12 },
318-
checkText: { color: '#FFF' },
319-
sectionTitle: { fontSize: 18, fontWeight: 'bold', color: '#333', marginBottom: 12 },
320-
activityCard: { backgroundColor: '#F0F6FF', borderRadius: 16, padding: 16, marginBottom: 24 },
321-
activityLabel: { fontSize: 14, color: '#555' },
322-
activityValue: { fontSize: 20, fontWeight: 'bold', marginVertical: 8, color: '#333' },
323-
lineChart: { height: 80, width: '100%' },
324-
timestampBadge: { position: 'absolute', right: 16, top: 16, backgroundColor: '#FFC0CB', borderRadius: 12, paddingVertical: 4, paddingHorizontal: 8 },
325-
timestampText: { fontSize: 12, color: '#FFF' },
326-
statsGrid: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between', marginBottom: 24 },
327-
statsCard: { width: '48%', backgroundColor: '#FFF', borderRadius: 16, padding: 16, marginBottom: 16, shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 10, elevation: 2 },
328-
statsCardSmall: { width: '48%', backgroundColor: '#FFF', borderRadius: 16, padding: 16, marginBottom: 16, alignItems: 'center', shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 10, elevation: 2 },
329-
statsLabel: { fontSize: 14, color: '#555' },
330-
statsValue: { fontSize: 18, fontWeight: 'bold', marginVertical: 8, color: '#333' },
331-
calOverlay: { position: 'absolute', top: 28, alignItems: 'center' },
332-
calOverlayText: { fontSize: 14, fontWeight: 'bold', color: '#FFF' },
333-
progressSection: { marginBottom: 24 },
334-
progressHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 },
335-
periodToggle: { fontSize: 14, color: '#777' },
336-
progressChart: { height: 100, width: '100%' },
337-
daysRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 8 },
338-
dayText: { fontSize: 12, color: '#777' },
339-
latestSection: { marginBottom: 24 },
340-
sectionHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 },
341-
seeMore: { fontSize: 14, color: '#70A1FF' },
342-
workoutItem: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#F9FAFF', borderRadius: 16, padding: 12, marginBottom: 12 },
343-
workoutIcon: { width: 40, height: 40, marginRight: 12 },
344-
workoutInfo: { flex: 1 },
345-
workoutType: { fontSize: 16, fontWeight: 'bold', color: '#333' },
346-
workoutMeta: { fontSize: 12, color: '#777', marginTop: 4 },
347-
arrowIcon: { width: 24, height: 24, tintColor: '#777' },
348-
});
349-
350-
export default HomeScreen;
1+
import HomeScreen from '@/app/home';
2+
export default HomeScreen;

KonditionExpo/app/_layout.tsx

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native
22
import { useFonts } from 'expo-font';
33
import { Stack } from 'expo-router';
44
import { StatusBar } from 'expo-status-bar';
5+
import { AuthProvider } from '@/contexts/AuthContext';
56
import 'react-native-reanimated';
67

78
import { useColorScheme } from '@/hooks/useColorScheme';
@@ -19,18 +20,22 @@ export default function RootLayout() {
1920
}
2021

2122
return (
22-
<UserProvider>
23-
<WorkoutProvider>
24-
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
25-
<Stack>
26-
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
27-
<Stack.Screen name="login" options={{ headerShown: false }} />
28-
<Stack.Screen name="workout" options={{ headerShown: false }} />
29-
<Stack.Screen name="+not-found" />
30-
</Stack>
31-
<StatusBar style="auto" />
32-
</ThemeProvider>
33-
</WorkoutProvider>
34-
</UserProvider>
23+
<AuthProvider>
24+
<UserProvider>
25+
<WorkoutProvider>
26+
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
27+
<Stack>
28+
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
29+
<Stack.Screen name="login" options={{ headerShown: false }} />
30+
<Stack.Screen name="workout" options={{ headerShown: false }} />
31+
<Stack.Screen name="+not-found" />
32+
</Stack>
33+
<StatusBar style="auto" />
34+
</ThemeProvider>
35+
</WorkoutProvider>
36+
</UserProvider>
37+
</AuthProvider>
38+
3539
);
3640
}
41+

0 commit comments

Comments
 (0)