Skip to content

Commit 5214c70

Browse files
committed
Cleaned up home and added new graph
1 parent 14a68fc commit 5214c70

File tree

1 file changed

+99
-59
lines changed

1 file changed

+99
-59
lines changed

KonditionExpo/app/home.tsx

Lines changed: 99 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,22 @@ import { router } from 'expo-router';
66
import { usePersonalBests } from "@/hooks/usePersonalBests";
77
import { Dialog } from '@/components/ui/Dialog';
88
import { Button } from '@/components/ui/Button';
9+
import { useWorkout } from '@/contexts/WorkoutContext';
10+
import { BarChart } from 'react-native-chart-kit';
11+
import { useEffect } from 'react';
12+
import { ProgressChart } from 'react-native-chart-kit';
913

1014
const { width } = Dimensions.get('window');
1115
//console.log(" 1 HomeScreen about to be rendered rendered");
16+
1217
const HomeScreen = () => {
13-
//console.log("2 HomeScreen rendered");
18+
const { workouts, getWorkouts } = useWorkout(); // <- include getWorkouts
1419
const { user } = useAuth();
20+
21+
useEffect(() => {
22+
getWorkouts();
23+
}, []);
24+
1525
if (!user) {
1626
console.warn("User context is undefined");
1727
return null;
@@ -38,6 +48,59 @@ const HomeScreen = () => {
3848
return 'Obesity Class 3';
3949
}, [bmiValue]);
4050

51+
const range = '7'; // fixed
52+
53+
const getDateLabels = (days: number) => {
54+
const labels = [];
55+
for (let i = days - 1; i >= 0; i--) {
56+
const d = new Date();
57+
d.setDate(d.getDate() - i);
58+
59+
// Skip every other label if days > 7
60+
const skip = days === 14 ? 2 : days === 30 ? 3 : 1;
61+
if (i % skip !== 0) {
62+
labels.push('');
63+
} else {
64+
labels.push(d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }));
65+
}
66+
}
67+
return labels;
68+
};
69+
70+
71+
72+
const { labels, data } = useMemo(() => {
73+
const nameToDuration: Record<string, number> = {};
74+
75+
workouts
76+
.filter(w => w.is_completed && w.name && (w.updated_at || w.completed_date))
77+
.forEach(w => {
78+
const end = new Date(w.updated_at ?? w.completed_date).getTime();
79+
const start = new Date(w.created_at).getTime();
80+
const duration = Math.round((end - start) / 60000); // in minutes
81+
82+
const name = w.name.trim();
83+
if (!nameToDuration[name]) {
84+
nameToDuration[name] = 0;
85+
}
86+
nameToDuration[name] += duration;
87+
});
88+
89+
const sorted = Object.entries(nameToDuration)
90+
.filter(([name, minutes]) => minutes > 0)
91+
.sort((a, b) => b[1] - a[1]); // descending
92+
93+
return {
94+
labels: sorted.map(([name]) => name),
95+
data: sorted.map(([, duration]) => duration),
96+
};
97+
}, [workouts]);
98+
99+
100+
101+
102+
//console.log("workouts", JSON.stringify(workouts, null, 2));
103+
41104
const [showBmiDialog, setShowBmiDialog] = useState(false);
42105

43106
const workoutProgressData = [20, 40, 30, 60, 90, 80, 70];
@@ -50,8 +113,8 @@ const HomeScreen = () => {
50113
const { pbs, loading } = usePersonalBests();
51114
const testPbs = pbs.length === 0 ? [{ metric: "Deadlift", value: 315, date: "2025-05-27" }] : pbs;
52115

53-
console.log('PBS LOADED:', pbs);
54-
console.log("Rendering personal bests section. pbs:", pbs, "loading:", loading);
116+
//console.log('PBS LOADED:', pbs);
117+
//console.log("Rendering personal bests section. pbs:", pbs, "loading:", loading);
55118

56119
return (
57120
<SafeAreaView style={styles.container}>
@@ -90,68 +153,45 @@ const HomeScreen = () => {
90153

91154
{/* Workout Progress */}
92155
<View style={styles.progressSection}>
93-
<View style={styles.progressHeader}>
94-
<Text style={styles.sectionTitle}>Workout Progress</Text>
95-
<TouchableOpacity onPress={() => {/* toggle weekly/monthly */}}>
96-
<Text style={styles.periodToggle}>Weekly ▼</Text>
97-
</TouchableOpacity>
98-
</View>
99-
<LineChart
100-
data={{
101-
labels: workoutDays,
102-
datasets: [
103-
{
104-
data: workoutProgressData,
105-
color: () => '#B07FFD',
106-
strokeWidth: 2,
107-
},
108-
],
109-
}}
110-
width={width - 64}
111-
height={100}
112-
chartConfig={{
113-
backgroundGradientFrom: '#fff',
114-
backgroundGradientTo: '#fff',
115-
color: () => '#B07FFD',
116-
strokeWidth: 2,
117-
}}
118-
bezier
119-
style={styles.progressChart}
120-
/>
121-
<View style={styles.daysRow}>
122-
{workoutDays.map(day => (
123-
<Text key={day} style={styles.dayText}>{day}</Text>
124-
))}
125-
</View>
126-
</View>
156+
<View style={styles.progressHeader}>
157+
<Text style={styles.sectionTitle}>Workout Minutes</Text>
158+
</View>
127159

128-
{/* Latest Workout */}
129-
<View style={[styles.latestSection, { backgroundColor: '#f0f0f0' }]}>
130-
<View style={styles.sectionHeader}>
131-
<Text style={styles.sectionTitle}>Latest Workout</Text>
132-
<TouchableOpacity onPress={() => alert('Workout List not yet implemented')}>
133-
<Text style={styles.seeMore}>See more</Text>
134-
</TouchableOpacity>
135-
</View>
136-
{latestWorkouts.map(w => (
137-
<TouchableOpacity key={w.id} style={styles.workoutItem} onPress={() => alert('Workout Details not yet implemented')}>
138-
<Image source={w.icon} style={styles.workoutIcon} />
139-
<View style={styles.workoutInfo}>
140-
<Text style={styles.workoutType}>{w.type}</Text>
141-
<Text style={styles.workoutMeta}>{w.calories} Calories Burn | {w.duration}</Text>
142-
</View>
143-
<Image source={require('../assets/images/arrow-right.png')} style={styles.arrowIcon} />
144-
</TouchableOpacity>
145-
))}
146-
</View>
160+
<View style={{ alignItems: 'center' }}>
161+
<BarChart
162+
data={{ labels, datasets: [{ data }] }}
163+
width={Math.max(width, labels.length * 60)}
164+
height={220}
165+
fromZero
166+
showValuesOnTopOfBars
167+
withInnerLines={true}
168+
withHorizontalLabels={false} // Hide Y-axis labels only
169+
chartConfig={{
170+
backgroundGradientFrom: '#fff',
171+
backgroundGradientTo: '#fff',
172+
color: () => '#70A1FF',
173+
decimalPlaces: 0,
174+
barPercentage: 0.6,
175+
propsForBackgroundLines: {
176+
stroke: '#E0E0E0',
177+
},
178+
formatYLabel: (yValue) => `${yValue}m`,
179+
}}
180+
style={{
181+
marginVertical: 8,
182+
borderRadius: 16,
183+
}}
184+
/>
185+
</View>
186+
187+
188+
189+
</View>
147190

148191
{/* Personal Bests */}
149192
<View style={[styles.latestSection, { paddingBottom: 16 }]}>
150193
<View style={styles.sectionHeader}>
151194
<Text style={styles.sectionTitle}>Personal Bests</Text>
152-
<TouchableOpacity onPress={() => alert('Full Personal Bests screen not implemented')}>
153-
<Text style={styles.seeMore}>See more</Text>
154-
</TouchableOpacity>
155195
</View>
156196

157197
{loading ? (

0 commit comments

Comments
 (0)