fitaiProto/apps/mobile/src/components/WeeklyProgressChart.tsx
2026-03-12 20:19:48 +01:00

135 lines
3.2 KiB
TypeScript

import React from "react";
import { View, Text, StyleSheet, Dimensions } from "react-native";
import { LineChart } from "react-native-chart-kit";
import { useTheme } from "../contexts/ThemeContext";
import type { WeeklyTrendData } from "../api/types";
interface WeeklyProgressChartProps {
weeklyData: WeeklyTrendData[];
title?: string;
}
export function WeeklyProgressChart({
weeklyData,
title = "Weekly Progress",
}: WeeklyProgressChartProps) {
const { colors, typography } = useTheme();
const screenWidth = Dimensions.get("window").width;
const labels = weeklyData.map((week: WeeklyTrendData) => week.weekLabel);
const checkInsData = weeklyData.map((week: WeeklyTrendData) => week.checkIns);
const goalsCompletedData = weeklyData.map(
(week: WeeklyTrendData) => week.goalsCompleted,
);
const chartConfig = {
backgroundColor: colors.surface,
backgroundGradientFrom: colors.surface,
backgroundGradientTo: colors.surface,
decimalPlaces: 0,
color: (opacity = 1) => `rgba(0, 102, 255, ${opacity})`,
labelColor: (opacity = 1) => colors.textTertiary,
propsForDots: {
r: "5",
strokeWidth: "2",
stroke: colors.primary,
},
};
const data = {
labels,
datasets: [
{
data: checkInsData,
color: () => colors.primary,
strokeWidth: 3,
},
{
data: goalsCompletedData,
color: () => colors.success,
strokeWidth: 3,
},
],
legend: ["Check-ins", "Goals"],
};
return (
<View style={styles.container}>
{title && (
<Text
style={[
typography.h4,
{ color: colors.textPrimary, marginBottom: 16 },
]}
>
{title}
</Text>
)}
<View style={styles.chartContainer}>
<LineChart
data={data}
width={screenWidth - 80}
height={180}
chartConfig={chartConfig}
bezier
style={styles.chart}
withInnerLines={true}
withOuterLines={false}
withVerticalLabels={true}
withHorizontalLabels={true}
fromZero={true}
/>
</View>
<View style={styles.legend}>
<View style={styles.legendItem}>
<View
style={[styles.legendDot, { backgroundColor: colors.primary }]}
/>
<Text style={[typography.caption, { color: colors.textSecondary }]}>
Check-ins
</Text>
</View>
<View style={styles.legendItem}>
<View
style={[styles.legendDot, { backgroundColor: colors.success }]}
/>
<Text style={[typography.caption, { color: colors.textSecondary }]}>
Goals
</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
borderRadius: 16,
padding: 4,
},
chartContainer: {
alignItems: "center",
marginBottom: 12,
},
chart: {
marginVertical: 8,
borderRadius: 12,
},
legend: {
flexDirection: "row",
justifyContent: "center",
gap: 24,
paddingTop: 8,
},
legendItem: {
flexDirection: "row",
alignItems: "center",
gap: 8,
},
legendDot: {
width: 10,
height: 10,
borderRadius: 5,
},
});