Josh Bruce Online

Hearts Fitness Tracking PWA - Complete Documentation

Table of Contents

  1. Overview
  2. Technical Architecture
  3. Core Features
  4. Exercise Database
  5. Workout Programming
  6. Nutrition System
  7. Progressive Web App Features
  8. User Interface
  9. Data Management
  10. Development Setup
  11. API Reference
  12. Troubleshooting

Overview

Hearts (6♥) is a research-based Progressive Web App designed specifically for teenage muscle building and fitness tracking. The application combines evidence-based exercise programming with intuitive progress tracking, creating a comprehensive fitness companion that works both online and offline.

Key Statistics

Primary Goals

Technical Architecture

Frontend Stack

// Core Technologies
- Framework: React 18 (via CDN)
- Styling: Custom CSS with CSS Variables
- State Management: React Hooks (useState, useEffect, useCallback)
- Build Process: No build step - direct browser execution
- PWA: Custom service worker implementation

Backend Infrastructure

// Firebase Integration
- Database: Firestore (NoSQL document database)
- Authentication: None (single-user design)
- Storage: Firebase Storage (for progress photos)
- Hosting: GitHub Pages
- Offline Storage: Service Worker caching + localStorage

Service Worker Architecture

// sw.js - Core Functionality
const CACHE_NAME = 'fittrack-pro-v1';
const urlsToCache = [
  './',
  './index.html',
  './manifest.json',
  // External dependencies cached for offline use
];

// Features:
- Resource caching for offline functionality
- Push notification scheduling
- Background sync capabilities
- Daily notification system (23:59 schedule)

PWA Manifest

{
  "name": "6♥",
  "short_name": "6♥",
  "description": "Your personal fitness tracking companion",
  "display": "standalone",
  "background_color": "#FAFAFA",
  "theme_color": "#3B82F6",
  "orientation": "portrait-primary"
}

Core Features

1. Workout Logging System

The workout logging system provides real-time exercise tracking with integrated timers and form guidance.

Exercise Popup Interface

// Exercise detail popup includes:
- Exercise name and muscle targets
- Form instruction carousel
- Weight input with rounded styling
- Set/rep tracking interface
- Rest timer integration
- Progress notes section

Weight Tracking Implementation

// Firebase structure for exercise weights
Collection: 'stats'
Document: '{exercise_name}'
Fields: {
  starting_weight: number,
  current_weight: number,
  last_updated: timestamp
}

// Auto-populated from previous sessions
const loadExerciseWeight = async (exerciseName) => {
  const doc = await db.collection('stats').doc(exerciseName).get();
  return doc.exists ? doc.data().current_weight : '';
};

2. Progress Tracking Dashboard

// Daily metrics tracked:
- Workout completion percentage
- Water intake (ml consumed vs target)
- Hydration goal progress
- Calorie tracking with visual indicators
- Exercise weight progressions
- Workout duration vs targets

Progress Cards Interface

// Dashboard cards include:
1. Daily Summary Card
   - Date display with day name
   - Quick stats overview
   - Progress percentage rings

2. Hydration Tracking Card
   - 250ml increment buttons
   - Visual progress bar
   - Daily target (4000ml default)
   - Streak tracking

3. Calorie Tracking Card
   - Meal logging interface
   - Daily target progress
   - Quick-add common foods

4. Notification Settings Card
   - Push notification toggle
   - Daily reminder settings
   - Permission management

3. Push Notification System

The app implements a sophisticated notification system using service workers for persistent notifications.

Daily Notification Scheduler

// Service worker notification scheduling
function scheduleNextNotification() {
  const now = new Date();
  const target = new Date();
  target.setHours(23, 59, 0, 0);
  
  if (now > target) {
    target.setDate(target.getDate() + 1);
  }
  
  const timeUntilNotification = target.getTime() - now.getTime();
  
  notificationTimeout = setTimeout(() => {
    sendDailyNotification();
    scheduleNextNotification(); // Reschedule for next day
  }, timeUntilNotification);
}

Notification Content

// Daily summary notification format
const notificationData = {
  title: `${dateString} Summary`,
  body: 'Check your daily progress!',
  icon: './icon-192x192.png',
  badge: './icon-192x192.png',
  tag: 'daily-summary',
  requireInteraction: false,
  actions: [{
    action: 'open',
    title: 'View Progress'
  }]
};

Exercise Database

The Hearts app includes a comprehensive exercise database organized by muscle categories, each with detailed form guidance and progression tracking.

Database Structure

// Five main exercise categories:
1. Arms (arms_exercises.json)
2. Shoulders (shoulders_exercises.json) 
3. Chest (chest_exercises.json)
4. Core (core_exercises.json)
5. Back (back_exercises.json)

Exercise Data Schema

// Each exercise includes:
{
  "exercise_name": {
    "name": "Display name",
    "primary_muscles": ["target muscle groups"],
    "secondary_muscles": ["supporting muscles"],
    "type": "compound|isolation",
    "difficulty": "beginner|intermediate|advanced",
    "home_compatible": boolean,
    "gym_compatible": boolean,
    "equipment_needed": {
      "home": ["required equipment"],
      "gym": ["gym equipment options"]
    },
    "sets_reps": {
      "week_1": { "sets": 3, "reps": "8-10", "rest_seconds": 90 },
      "week_2": { "sets": 4, "reps": "10-12", "rest_seconds": 90 }
    },
    "form_cues": ["detailed form instructions"],
    "common_mistakes": ["what to avoid"],
    "progression_options": ["advancement strategies"],
    "regression_options": ["easier variations"],
    "youtube_tutorial": "video URL",
    "research_notes": "scientific backing",
    "safety_tips": ["injury prevention"],
    "breath_pattern": "breathing instruction",
    "tempo": "timing guidance"
  }
}

Arms Exercises

Chest Exercises

Core Exercises

Exercise Video Integration

Each exercise includes embedded YouTube tutorials from certified fitness professionals, ensuring proper form education and injury prevention.

Workout Programming

Hearts implements a research-based two-week priority muscle building program designed specifically for teenagers.

Program Philosophy

// Core principles:
- Session Duration: 30 minutes maximum
- Weekly Frequency: 4 training days + 1 integration day
- Rest Days: 2 complete rest days
- Priority Muscles: Arms, shoulders, abs, chest
- Superset Focus: 50% time reduction strategy
- Volume Distribution: 10-20 sets per muscle weekly

Weekly Split Structure

// 7-day program cycle:
Day 1: Arms & Shoulders Priority (28 minutes)
Day 2: Chest & Abs Priority (26 minutes)
Day 3: Active Recovery (15-20 minutes)
Day 4: Arms & Chest Focus (29 minutes)
Day 5: Shoulders & Abs Focus (27 minutes)
Day 6: Full Upper Body Integration (30 minutes)
Day 7: Complete Rest

Superset Implementation

// Example Day 1 Structure:
Superset 1: EZ Bar Curls + Overhead Tricep Extension
- 3 sets x 8-10 reps each
- 15 seconds rest between exercises
- 90 seconds rest between rounds

Superset 2: Dumbbell Shoulder Press + Lateral Raises
- 3 sets x 8-10 + 12-15 reps
- 15 seconds rest between exercises
- 90 seconds rest between rounds

Superset 3: Hammer Curls + Rear Delt Flyes
- 2 sets x 10-12 + 12-15 reps
- 10 seconds rest between exercises
- 60 seconds rest between rounds

Home vs Gym Variations

The program provides equivalent home and gym versions for each workout:

Gym Version Features

Home Version Features

Progressive Overload System

// Week 1 to Week 2 progression:
General Rules:
- Reps: Add 2-3 reps when possible
- Sets: Add 1 set for key exercises
- Weight: Increase 2.5-5% if completing all reps easily
- Rest: Maintain 1-2 minutes for time efficiency

Specific Exercise Progressions:
- Dumbbell Curls: 3x8-10  4x10-12
- Triangle Push-ups: 3x6-8  4x8-10
- Plank: 2x30-45s  3x45-60s

Nutrition System

Hearts includes a comprehensive nutrition tracking system with pre-designed recipes optimized for teenage muscle building.

Nutrition Database

The app includes 25+ recipes across 9 categories, each with complete macro breakdowns and preparation instructions.

Recipe Categories

// Recipe organization:
pre_workout: ["banana_oats", "energy_bites", "peanut_butter_toast"]
post_workout: ["protein_smoothie", "chocolate_milk", "recovery_shake"]
high_protein_snack: ["greek_yogurt_berries", "protein_muffin", "protein_bar_homemade"]
high_calorie_snack: ["nuts_dates", "trail_mix"]
bedtime_protein: ["cottage_cheese_fruit", "casein_pudding"]
balanced_snack: ["avocado_toast", "hummus_veggies", "apple_almond_butter"]
breakfast_replacement: ["smoothie_bowl", "overnight_oats", "protein_pancakes"]
meal_replacement: ["quinoa_salad"]
evening_treat: ["milk_cookies"]

Sample Recipe: Post-Workout Protein Smoothie

{
  "name": "Post-Workout Protein Smoothie",
  "prep_time_minutes": 3,
  "nutrition": {
    "calories": 520,
    "protein_g": 35,
    "carbs_g": 58,
    "fat_g": 12,
    "fiber_g": 6
  },
  "ingredients": [
    {"item": "Whey protein powder", "amount": "30g", "notes": "Vanilla or chocolate"},
    {"item": "Frozen banana", "amount": "1 large", "notes": "Natural sweetness and carbs"},
    {"item": "Whole milk", "amount": "300ml", "notes": "Additional protein"},
    {"item": "Rolled oats", "amount": "30g", "notes": "Complex carbs"},
    {"item": "Peanut butter", "amount": "1 tbsp", "notes": "Healthy fats"}
  ],
  "timing_notes": "Consume within 30-60 minutes post-workout",
  "research_basis": "25g+ protein triggers muscle protein synthesis"
}

Daily Nutrition Targets

// Optimized for 69kg teenager:
daily_protein_goal_g: "233-251"
daily_calories_goal: "3730-4030"
post_workout_protein_g: "20-30"
post_workout_carbs_g: "30-50"
pre_workout_timing_minutes: 30
post_workout_timing_minutes: 60

Meal Timing Strategy

// Optimized nutrient timing:
Pre-workout (30 min): Fast-digesting carbs, minimal fat
Post-workout (60 min): High protein + moderate carbs
Evening: Slow-digesting protein (casein)
Throughout day: Balanced macro distribution

Progressive Web App Features

Hearts is designed as a comprehensive PWA with native app-like functionality.

Installation Process

// App installation triggers:
1. Custom install prompt after 3 visits
2. Add to homescreen prompt for mobile
3. Desktop installation via browser
4. Automatic service worker registration

Offline Functionality

// Cached resources for offline use:
- Complete application shell
- Exercise database (all JSON files)
- Essential images and icons
- Recent workout data
- User progress history

// Background sync capabilities:
- Queue workout logs when offline
- Sync data when connection restored
- Persist user inputs locally
- Automatic conflict resolution

Native Features Integration

// Device capabilities utilized:
- Push notifications for daily reminders
- Camera access for progress photos
- Touch/haptic feedback for interactions
- Fullscreen mode for immersive workouts
- Background sync for data persistence

Cross-Platform Compatibility

// Supported platforms:
- iOS Safari (iOS 11.3+)
- Android Chrome (Chrome 67+)
- Desktop browsers (Chrome, Firefox, Edge)
- Tablet devices (optimized layout)

// Platform-specific optimizations:
- iOS: Haptic feedback integration
- Android: Enhanced notification support
- Desktop: Keyboard navigation
- Tablet: Responsive grid layouts

User Interface

Hearts features a modern, accessible interface optimized for touch interactions and mobile usage.

Design System

/* Color Palette */
:root {
  --background-primary: #0F0F0F;
  --background-secondary: #1A1A1A;
  --text-primary: #FFFFFF;
  --text-secondary: #A1A1AA;
  --accent-blue: #60A5FA;
  --accent-green: #34D399;
  --accent-purple: #A78BFA;
}

/* Typography Scale */
.heading-xl { font-size: 2.25rem; font-weight: 700; }
.heading-lg { font-size: 1.875rem; font-weight: 600; }
.body-lg { font-size: 1.125rem; line-height: 1.6; }
.body-base { font-size: 1rem; line-height: 1.5; }

Component Architecture

// Core UI components:
1. Dashboard Cards
   - Rounded corners (12px border-radius)
   - Consistent padding (20px)
   - Shadow depth for hierarchy
   - Responsive grid layout

2. Exercise Interface
   - Modal overlay design
   - Carousel for form instructions
   - Progress indicators
   - Touch-optimized controls

3. Input Components
   - Rounded input fields (50px height)
   - Haptic feedback on interaction
   - Clear visual focus states
   - Error state handling

4. Navigation
   - Bottom tab bar (mobile)
   - Breadcrumb navigation (desktop)
   - Gesture-based interactions
   - Smooth transitions

Responsive Design

/* Breakpoint system */
@media (max-width: 768px) {
  /* Mobile optimizations */
  .dashboard-grid { grid-template-columns: 1fr; }
  .exercise-modal { height: 100vh; }
  .input-field { font-size: 16px; } /* Prevents zoom on iOS */
}

@media (min-width: 1024px) {
  /* Desktop enhancements */
  .dashboard-grid { grid-template-columns: repeat(2, 1fr); }
  .exercise-modal { max-width: 600px; }
  .sidebar-navigation { display: block; }
}

Accessibility Features

// WCAG 2.1 AA compliance:
- Semantic HTML structure
- ARIA labels for interactive elements
- High contrast color ratios (4.5:1 minimum)
- Keyboard navigation support
- Screen reader optimization
- Focus management for modals
- Alternative text for images
- Consistent navigation patterns

Data Management

Hearts uses Firebase Firestore for cloud storage with local caching for offline functionality.

Database Schema

// Firestore collections structure:
/stats/{exerciseName}
  - starting_weight: number
  - current_weight: number
  - last_updated: timestamp

/user_progress/{date}
  - workouts_completed: number
  - water_ml_consumed: number
  - calorie_intake: number
  - notes: string

/workout_logs/{workoutId}
  - date: timestamp
  - exercises: array
  - duration_minutes: number
  - completion_percentage: number

Local Storage Strategy

// localStorage usage:
localStorage.setItem('userPreferences', JSON.stringify({
  hydrationGoal: 4000,
  calorieGoal: 3800,
  preferredWorkoutTime: 'morning',
  notificationsEnabled: true
}));

// sessionStorage for temporary data:
sessionStorage.setItem('currentWorkout', JSON.stringify({
  startTime: Date.now(),
  exercisesCompleted: [],
  currentExercise: 'dumbbell_curls'
}));

Data Synchronization

// Sync strategy:
1. Online: Direct Firebase operations
2. Offline: Queue operations in localStorage
3. Reconnection: Batch sync queued operations
4. Conflict resolution: Last-write-wins with timestamps

// Example sync function:
const syncPendingData = async () => {
  const pendingOps = JSON.parse(localStorage.getItem('pendingOperations') || '[]');
  for (const op of pendingOps) {
    try {
      await executeFirebaseOperation(op);
      removePendingOperation(op.id);
    } catch (error) {
      console.log('Sync failed for operation:', op.id);
    }
  }
};

Performance Optimizations

// Data loading strategies:
- Lazy loading for exercise images
- Pagination for workout history
- Compression for large datasets
- CDN usage for static assets
- Service worker caching
- Bundle size optimization

Development Setup

Prerequisites

# Required tools:
- Git
- Modern web browser (Chrome/Firefox/Safari)
- Text editor (VS Code recommended)
- Firebase CLI (optional for advanced features)
- Local web server (for development)

Installation Steps

# 1. Clone the repository
git clone https://github.com/username/hearts-fitness-app.git
cd hearts-fitness-app

# 2. Set up Firebase project
# - Create new Firebase project at console.firebase.google.com
# - Enable Firestore database
# - Copy configuration to index.html

# 3. Configure Firebase
# Replace firebaseConfig in index.html with your project config:
const firebaseConfig = {
  apiKey: "your-api-key",
  authDomain: "your-project.firebaseapp.com",
  projectId: "your-project-id",
  storageBucket: "your-project.appspot.com",
  messagingSenderId: "123456789",
  appId: "your-app-id"
};

# 4. Start local development server
# Option A: Python
python -m http.server 8000

# Option B: Node.js http-server
npx http-server -p 8000

# Option C: Live Server (VS Code extension)
# Right-click index.html -> "Open with Live Server"

# 5. Access application
# Navigate to http://localhost:8000

Firebase Setup

// 1. Firestore Security Rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Allow read/write for all documents (single-user app)
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

// 2. Storage Rules (for progress photos)
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true;
    }
  }
}

Development Workflow

# 1. Feature development
git checkout -b feature/new-exercise-tracking
# Make changes
git add .
git commit -m "Add weight tracking for exercises"

# 2. Testing
# - Test offline functionality
# - Test PWA installation
# - Test across devices/browsers
# - Validate Firebase operations

# 3. Deployment
git push origin main
# GitHub Pages will automatically deploy

Building for Production

// Production optimizations:
1. Minify CSS and JavaScript
2. Optimize images (WebP format)
3. Enable compression (gzip/brotli)
4. Set up CDN for assets
5. Configure proper caching headers
6. Test PWA requirements

API Reference

Core Functions

Workout Management

// Load today's workout
const loadTodaysWorkout = async () => {
  const today = new Date().toISOString().split('T')[0];
  const workoutDoc = await db.collection('workouts').doc(today).get();
  return workoutDoc.exists ? workoutDoc.data() : getDefaultWorkout();
};

// Save workout progress
const saveWorkoutProgress = async (workoutData) => {
  const today = new Date().toISOString().split('T')[0];
  await db.collection('workouts').doc(today).set(workoutData, { merge: true });
};

// Calculate workout completion percentage
const calculateCompletionPercentage = (completedSets, totalSets) => {
  return Math.round((completedSets / totalSets) * 100);
};

Exercise Weight Tracking

// Load exercise weight
const loadExerciseWeight = async (exerciseName) => {
  try {
    const doc = await db.collection('stats').doc(exerciseName).get();
    if (doc.exists) {
      return doc.data().current_weight || '';
    }
    return '';
  } catch (error) {
    console.error('Error loading exercise weight:', error);
    return '';
  }
};

// Save exercise weight
const saveExerciseWeight = async (exerciseName, weight) => {
  try {
    const doc = await db.collection('stats').doc(exerciseName).get();
    const data = {
      current_weight: parseFloat(weight),
      last_updated: firebase.firestore.FieldValue.serverTimestamp()
    };
    
    if (!doc.exists) {
      data.starting_weight = parseFloat(weight);
    }
    
    await db.collection('stats').doc(exerciseName).set(data, { merge: true });
  } catch (error) {
    console.error('Error saving exercise weight:', error);
  }
};

Progress Tracking

// Update hydration progress
const updateHydrationProgress = async (amountMl) => {
  const today = new Date().toISOString().split('T')[0];
  try {
    await db.collection('daily_progress').doc(today).update({
      water_consumed_ml: firebase.firestore.FieldValue.increment(amountMl),
      last_updated: firebase.firestore.FieldValue.serverTimestamp()
    });
  } catch (error) {
    // Document doesn't exist, create it
    await db.collection('daily_progress').doc(today).set({
      water_consumed_ml: amountMl,
      water_goal_ml: 4000,
      created_at: firebase.firestore.FieldValue.serverTimestamp()
    });
  }
};

// Get daily progress summary
const getDailyProgress = async (date = null) => {
  const targetDate = date || new Date().toISOString().split('T')[0];
  const doc = await db.collection('daily_progress').doc(targetDate).get();
  return doc.exists ? doc.data() : getDefaultProgress();
};

Notification Management

// Request notification permission
const requestNotificationPermission = async () => {
  if (!('Notification' in window)) {
    return 'not-supported';
  }
  
  if (Notification.permission === 'granted') {
    return 'granted';
  }
  
  const permission = await Notification.requestPermission();
  return permission;
};

// Schedule daily notification
const scheduleDailyNotification = () => {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(registration => {
      registration.active.postMessage({
        type: 'SCHEDULE_NOTIFICATION',
        data: { time: '23:59' }
      });
    });
  }
};

Exercise Database Integration

// Load exercise data
const loadExerciseData = async (category, exerciseId) => {
  try {
    const response = await fetch(`${category}_exercises.json`);
    const data = await response.json();
    return data.exercises[exerciseId];
  } catch (error) {
    console.error('Error loading exercise data:', error);
    return null;
  }
};

// Get exercises by category
const getExercisesByCategory = async (category) => {
  try {
    const response = await fetch(`${category}_exercises.json`);
    const data = await response.json();
    return Object.keys(data.exercises).map(key => ({
      id: key,
      ...data.exercises[key]
    }));
  } catch (error) {
    console.error('Error loading exercises:', error);
    return [];
  }
};

Utility Functions

// Format time duration
const formatDuration = (minutes) => {
  const hours = Math.floor(minutes / 60);
  const mins = minutes % 60;
  if (hours > 0) {
    return `${hours}h ${mins}m`;
  }
  return `${mins}m`;
};

// Calculate progress percentage
const calculateProgress = (current, target) => {
  return Math.min(100, Math.round((current / target) * 100));
};

// Get current week day
const getCurrentWeekDay = () => {
  const date = new Date();
  const day = date.getDay();
  return day === 0 ? 7 : day; // Convert Sunday (0) to 7
};

// Haptic feedback (iOS)
const triggerHapticFeedback = (type = 'light') => {
  if (window.navigator && window.navigator.vibrate) {
    const patterns = {
      light: [10],
      medium: [50],
      heavy: [100]
    };
    window.navigator.vibrate(patterns[type] || patterns.light);
  }
};

Troubleshooting

Common Issues and Solutions

PWA Installation Issues

// Issue: "Add to Home Screen" not appearing
// Solution: Ensure PWA requirements are met
const checkPWARequirements = () => {
  const checks = {
    manifest: document.querySelector('link[rel="manifest"]') !== null,
    serviceWorker: 'serviceWorker' in navigator,
    https: location.protocol === 'https:' || location.hostname === 'localhost',
    icons: true // Check manifest.json has required icon sizes
  };
  
  console.log('PWA Requirements:', checks);
  return Object.values(checks).every(check => check === true);
};

Firebase Connection Issues

// Issue: Firebase operations failing
// Solution: Check configuration and network
const testFirebaseConnection = async () => {
  try {
    await db.collection('test').add({ timestamp: new Date() });
    console.log('Firebase connection successful');
    return true;
  } catch (error) {
    console.error('Firebase connection failed:', error);
    // Check if offline, enable offline persistence
    if (error.code === 'unavailable') {
      enableOfflineMode();
    }
    return false;
  }
};

const enableOfflineMode = () => {
  db.enablePersistence()
    .then(() => console.log('Offline persistence enabled'))
    .catch(err => console.log('Offline persistence failed:', err));
};

Notification Issues

// Issue: Notifications not working on iOS
// Solution: Proper feature detection and fallback
const checkNotificationSupport = () => {
  const support = {
    api: 'Notification' in window,
    serviceWorker: 'serviceWorker' in navigator,
    permission: Notification.permission
  };
  
  // iOS Safari limitations
  const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
  if (isIOS) {
    support.iosLimitations = 'iOS requires user gesture for notifications';
  }
  
  return support;
};

Performance Issues

// Issue: App loading slowly
// Solution: Implement performance optimizations
const optimizePerformance = () => {
  // Lazy load images
  const images = document.querySelectorAll('img[data-src]');
  const imageObserver = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.src = entry.target.dataset.src;
        imageObserver.unobserve(entry.target);
      }
    });
  });
  
  images.forEach(img => imageObserver.observe(img));
  
  // Preload critical resources
  const preloadLinks = [
    'arms_exercises.json',
    'shoulders_exercises.json',
    'chest_exercises.json'
  ];
  
  preloadLinks.forEach(href => {
    const link = document.createElement('link');
    link.rel = 'preload';
    link.href = href;
    link.as = 'fetch';
    link.crossOrigin = 'anonymous';
    document.head.appendChild(link);
  });
};

Data Sync Issues

// Issue: Data not syncing between devices
// Solution: Implement proper sync mechanism
const handleDataSync = () => {
  // Listen for online status
  window.addEventListener('online', async () => {
    console.log('Connection restored, syncing data...');
    await syncPendingOperations();
  });
  
  window.addEventListener('offline', () => {
    console.log('Connection lost, enabling offline mode...');
    showOfflineNotification();
  });
};

const syncPendingOperations = async () => {
  const pending = JSON.parse(localStorage.getItem('pendingSync') || '[]');
  for (const operation of pending) {
    try {
      await executeOperation(operation);
      removePendingOperation(operation.id);
    } catch (error) {
      console.error('Sync failed for operation:', operation.id, error);
    }
  }
};

Debug Mode

// Enable debug mode for troubleshooting
const enableDebugMode = () => {
  window.DEBUG = true;
  
  // Console logging for all Firebase operations
  const originalFirestoreSet = db.collection('').constructor.prototype.set;
  db.collection('').constructor.prototype.set = function(...args) {
    if (window.DEBUG) console.log('Firestore SET:', this.path, args);
    return originalFirestoreSet.apply(this, args);
  };
  
  // Performance monitoring
  const performanceObserver = new PerformanceObserver((list) => {
    if (window.DEBUG) {
      list.getEntries().forEach(entry => {
        console.log('Performance:', entry.name, entry.duration + 'ms');
      });
    }
  });
  
  performanceObserver.observe({ entryTypes: ['navigation', 'resource'] });
};

Browser Compatibility

// Check browser compatibility
const checkBrowserSupport = () => {
  const features = {
    serviceWorker: 'serviceWorker' in navigator,
    indexedDB: 'indexedDB' in window,
    fetch: 'fetch' in window,
    promise: 'Promise' in window,
    asyncAwait: (async () => {})().constructor.name === 'AsyncFunction'
  };
  
  const unsupported = Object.entries(features)
    .filter(([feature, supported]) => !supported)
    .map(([feature]) => feature);
  
  if (unsupported.length > 0) {
    console.warn('Unsupported features:', unsupported);
    showCompatibilityWarning(unsupported);
  }
  
  return unsupported.length === 0;
};

Conclusion

Hearts represents a comprehensive approach to teenage fitness tracking, combining research-based programming with modern web technologies. The app’s offline-first design, detailed exercise database, and progressive notification system create a reliable fitness companion that grows with the user’s fitness journey.

Key Success Factors

  1. Evidence-Based Programming: 178+ peer-reviewed studies inform every aspect
  2. User-Centric Design: Optimized for teenage users with intuitive interfaces
  3. Offline Reliability: Full functionality without internet dependency
  4. Progressive Enhancement: Native app features through PWA technology
  5. Comprehensive Tracking: Workout, nutrition, and progress monitoring
  6. Educational Focus: Proper form guidance and exercise progression

Future Development

Hearts demonstrates how modern web technologies can create powerful, accessible fitness applications that rival native apps while maintaining broad compatibility and offline functionality.