import React, { useState, useEffect } from "react"; import { View, Text, StyleSheet, ActivityIndicator } from "react-native"; import { LinearGradient } from "expo-linear-gradient"; import { Ionicons } from "@expo/vector-icons"; import { theme } from "../styles/theme"; import { useStatistics } from "../contexts/StatisticsContext"; import type { WeeklyTrendData } from "../api/types"; import log from "../utils/logger"; export function WeeklyProgressWidget() { const { statistics, loading, refetchStatistics } = useStatistics(); const [weeklyData, setWeeklyData] = useState([]); useEffect(() => { refetchStatistics(); }, [refetchStatistics]); useEffect(() => { if (statistics?.weeklyTrend) { log.debug("WeeklyProgressWidget - Processing weekly trend", { weeklyTrendLength: statistics.weeklyTrend.length, weeklyTrend: statistics.weeklyTrend, statisticsKeys: Object.keys(statistics), }); // Get last 4 weeks for compact display const last4Weeks = statistics.weeklyTrend.slice(-4); setWeeklyData(last4Weeks); log.debug("WeeklyProgressWidget - Set weekly data", { last4Weeks, }); } else { log.debug("WeeklyProgressWidget - No weekly trend data", { hasStatistics: !!statistics, statistics, }); } }, [statistics]); if (loading) { return ( ); } if (weeklyData.length === 0) { return null; } // Calculate totals from last 4 weeks const totalCheckIns = weeklyData.reduce( (sum, week) => sum + week.checkIns, 0, ); const totalGoals = weeklyData.reduce( (sum, week) => sum + week.goalsCompleted, 0, ); const avgProgress = weeklyData.reduce((sum, week) => sum + week.averageProgress, 0) / weeklyData.length; // Get max value for scaling bars const maxCheckIns = Math.max(...weeklyData.map((w) => w.checkIns), 1); return ( Weekly Progress Last 4 weeks {totalCheckIns} Check-ins {totalGoals} Goals Met {Math.round(avgProgress)}% Avg Progress {weeklyData.map((week, index) => { const barHeight = (week.checkIns / maxCheckIns) * 60; return ( {week.weekLabel} ); })} ); } const styles = StyleSheet.create({ container: { paddingHorizontal: 20, marginBottom: 16, }, card: { borderRadius: theme.borderRadius["2xl"], padding: 20, ...theme.shadows.medium, }, header: { flexDirection: "row", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 20, }, title: { fontSize: theme.typography.fontSize.xl, fontWeight: theme.typography.fontWeight.bold, color: theme.colors.white, marginBottom: 4, }, subtitle: { fontSize: theme.typography.fontSize.sm, color: "rgba(255, 255, 255, 0.8)", }, iconContainer: { backgroundColor: "rgba(255, 255, 255, 0.2)", width: 48, height: 48, borderRadius: 24, justifyContent: "center", alignItems: "center", }, statsRow: { flexDirection: "row", justifyContent: "space-around", marginBottom: 20, backgroundColor: "rgba(255, 255, 255, 0.15)", borderRadius: theme.borderRadius.xl, padding: 16, }, statItem: { alignItems: "center", flex: 1, }, statValue: { fontSize: theme.typography.fontSize["2xl"], fontWeight: theme.typography.fontWeight.bold, color: theme.colors.white, marginBottom: 4, }, statLabel: { fontSize: theme.typography.fontSize.xs, color: "rgba(255, 255, 255, 0.7)", textAlign: "center", }, statDivider: { width: 1, backgroundColor: "rgba(255, 255, 255, 0.2)", marginHorizontal: 8, }, chartContainer: { flexDirection: "row", justifyContent: "space-around", alignItems: "flex-end", height: 80, }, barContainer: { alignItems: "center", flex: 1, }, barWrapper: { height: 60, justifyContent: "flex-end", marginBottom: 6, }, bar: { width: 24, backgroundColor: "rgba(255, 255, 255, 0.9)", borderRadius: 4, minHeight: 4, }, barLabel: { fontSize: 10, color: "rgba(255, 255, 255, 0.7)", fontWeight: "500", }, });