import React, { useState, useEffect, useRef, useLayoutEffect } from 'react'; import { Trash2, Dumbbell, Utensils, User, ChevronRight, ChevronDown, ChevronUp, Activity, X, Droplets, BookOpen, Info, PlusCircle, Sparkles, Camera, ClipboardList, RefreshCw, Copy, Settings, LogOut, ShoppingCart, Loader2, Phone, Plus, Heart, GripVertical, Upload, Video } from 'lucide-react'; import { GoogleGenerativeAI } from "@google/generative-ai"; import SignupScreen from './SignupScreen'; import { WORKOUT_ROUTINES, TRAINING_PLANS } from './workoutData'; import { getCurrentUser, signInWithGoogle, signOut } from './firebase'; import { isHealthKitAvailable, requestHealthKitAuthorization, getTodaySummary, getHealthSyncSettings, saveHealthSyncSettings, getAuthorizationStatus, getHealthDataForDate } from './healthKit'; // --- CONFIGURATION --- const GEMINI_API_KEY = import.meta.env.VITE_GEMINI_API_KEY; // Updated Component: Accepts onRemoveWater and splits click area, with drag support const GlassDashboard = ({ stats, onAddWater, onRemoveWater }) => { const dragRef = React.useRef({ isDragging: false, startY: 0, lastUpdate: 0, rafId: null }); const totalPct = Math.min((stats.food / stats.adjustedGoal) * 100, 100); const waterPct = Math.min((stats.dailyWater / stats.waterGoal) * 100, 100); const proteinCals = stats.proteinTotal * 4; const carbsCals = stats.carbsTotal * 4; const fatCals = stats.fatTotal * 9; const totalMacroCals = proteinCals + carbsCals + fatCals || 1; const pPct = (proteinCals / totalMacroCals) * 100; const cPct = (carbsCals / totalMacroCals) * 100; const fPct = (fatCals / totalMacroCals) * 100; // Drag handlers for water - highly optimized with RAF const handleDragStart = (e) => { const clientY = e.touches ? e.touches[0].clientY : e.clientY; dragRef.current.isDragging = true; dragRef.current.startY = clientY; dragRef.current.lastUpdate = clientY; e.preventDefault(); }; const handleDragMove = (e) => { if (!dragRef.current.isDragging) return; // Cancel any pending animation frame if (dragRef.current.rafId) { cancelAnimationFrame(dragRef.current.rafId); } // Use RAF for smooth updates dragRef.current.rafId = requestAnimationFrame(() => { const clientY = e.touches ? e.touches[0].clientY : e.clientY; const deltaFromLast = dragRef.current.lastUpdate - clientY; const threshold = 40; // pixels per water increment if (Math.abs(deltaFromLast) >= threshold) { if (deltaFromLast > 0) { onAddWater(); } else { onRemoveWater(); } dragRef.current.lastUpdate = clientY; } }); }; const handleDragEnd = () => { dragRef.current.isDragging = false; if (dragRef.current.rafId) { cancelAnimationFrame(dragRef.current.rafId); dragRef.current.rafId = null; } }; return (
Today's Overview
Recalculates BMI and daily calorie targets automatically.
Syncs steps, calories burned, and workouts from Apple Health for the last 7 days.
Based on {stats.adjustedGoal} cal target.