Hearts is a comprehensive Progressive Web App (PWA) fitness tracking platform built with React. It provides workout logging, nutrition tracking, progress analytics, and goal management with a sophisticated iOS-inspired interface and Firebase backend integration.
hearts/
├── index.html # Main React application
├── manifest.json # PWA manifest configuration
├── sw.js # Service worker for offline functionality
├── 6hearts.jpeg # App icon and branding
├── firestore.rules # Firestore security rules
├── HEARTS_DOCUMENTATION.md # Existing technical documentation
├── research.md # Fitness research and methodology
├── webapp_implementation_guide.json # Implementation guidelines
├── workout-system-documentation.md # Workout system architecture
├── master_program_coordinator.json # Workout program coordination
├── weekly-workout-split.json # Workout split configurations
└── [exercise_type]_exercises.json # Exercise database files
├── arms_exercises.json
├── back_exercises.json
├── chest_exercises.json
├── core_exercises.json
├── shoulders_exercises.json
└── forearm_exercise_database.json
App
├── Header (stats display, timer)
├── TabBar (navigation system)
├── MainContent
│ ├── WorkoutView
│ │ ├── ExerciseSelector
│ │ ├── SetTracker
│ │ ├── RestTimer
│ │ └── ProgressChart
│ ├── NutritionView
│ │ ├── CalorieCounter
│ │ ├── MacroTracker
│ │ ├── MealPlanner
│ │ └── HydrationLog
│ ├── ProgressView
│ │ ├── WeightTracker
│ │ ├── AnalyticsCharts
│ │ ├── AchievementSystem
│ │ └── DataExport
│ └── SettingsView
│ ├── UserProfile
│ ├── Goals
│ ├── Preferences
│ └── DataManagement
{
"name": "6♥ - Fitness Tracker",
"short_name": "Hearts",
"description": "Your personal fitness tracking companion",
"start_url": "/hearts/",
"display": "standalone",
"theme_color": "#60A5FA",
"background_color": "#FAFAFA",
"orientation": "portrait",
"icons": [
{
"src": "6hearts.jpeg",
"sizes": "152x152",
"type": "image/jpeg",
"purpose": "any maskable"
}
]
}
// sw.js - Offline functionality
const CACHE_NAME = 'hearts-v1';
const urlsToCache = [
'/hearts/',
'/hearts/index.html',
'/hearts/manifest.json',
'/hearts/6hearts.jpeg'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => {
return response || fetch(event.request);
})
);
});
<!-- iOS-specific PWA features -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="6♥">
<link rel="apple-touch-icon" href="6hearts.jpeg">
<link rel="apple-touch-icon" sizes="152x152" href="6hearts.jpeg">
<link rel="apple-touch-icon" sizes="180x180" href="6hearts.jpeg">
<!-- iOS splash screens for different devices -->
<link rel="apple-touch-startup-image"
href="splash-2048x2732.png"
media="(device-width: 1024px) and (device-height: 1366px)">
:root {
/* Base colors */
--bg-primary: #FAFAFA;
--bg-secondary: #FFFFFF;
--bg-tertiary: #F3F4F6;
--text-primary: #1D1D1F;
--text-secondary: #6B7280;
--text-tertiary: #9CA3AF;
/* Accent colors */
--accent-blue: #3B82F6;
--accent-green: #10B981;
--accent-purple: #8B5CF6;
--accent-orange: #F59E0B;
--accent-amber: #F78200;
--accent-red: #EF4444;
/* Border and shadow */
--border-primary: #E5E7EB;
--border-secondary: #F3F4F6;
--shadow: rgba(0, 0, 0, 0.04);
--shadow-hover: rgba(0, 0, 0, 0.08);
--overlay: rgba(255, 255, 255, 0.98);
}
/* iOS-inspired typography */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue',
Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
font-optical-sizing: auto;
}
/* iOS safe area support */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
height: env(safe-area-inset-top, 0px);
background: var(--overlay);
z-index: 101;
}
/* Header with backdrop blur */
.header {
height: 6vh;
background: var(--overlay);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 1px 3px var(--shadow);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
}
/* Tab bar with safe area padding */
.tab-bar {
height: 10vh;
background: var(--overlay);
backdrop-filter: blur(20px);
padding: 20px 20px 40px 20px;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
}
// Example: chest_exercises.json
{
"exercises": [
{
"id": "bench_press",
"name": "Bench Press",
"muscle_groups": ["chest", "triceps", "shoulders"],
"equipment": ["barbell", "bench"],
"difficulty": "intermediate",
"instructions": [
"Lie flat on bench with feet firmly on ground",
"Grip barbell with hands wider than shoulder-width",
"Lower bar to chest with control",
"Press bar up explosively"
],
"tips": [
"Keep shoulder blades retracted",
"Maintain natural arch in lower back",
"Don't bounce bar off chest"
],
"variations": [
"Incline Bench Press",
"Decline Bench Press",
"Dumbbell Bench Press"
]
}
]
}
// Workout session structure
const workoutSession = {
id: generateId(),
date: new Date().toISOString(),
startTime: Date.now(),
endTime: null,
exercises: [
{
exerciseId: 'bench_press',
sets: [
{
reps: 10,
weight: 185,
restTime: 120, // seconds
completed: true,
notes: 'Felt strong today'
}
]
}
],
totalVolume: 0, // calculated
duration: 0, // calculated
notes: 'Great chest workout'
};
// master_program_coordinator.json
{
"programs": {
"push_pull_legs": {
"name": "Push/Pull/Legs Split",
"frequency": 6,
"days": {
"push": {
"muscle_groups": ["chest", "shoulders", "triceps"],
"exercises": ["bench_press", "shoulder_press", "tricep_dips"]
},
"pull": {
"muscle_groups": ["back", "biceps"],
"exercises": ["pull_ups", "rows", "bicep_curls"]
},
"legs": {
"muscle_groups": ["quads", "hamstrings", "glutes"],
"exercises": ["squats", "deadlifts", "lunges"]
}
}
}
}
}
// Nutrition tracking system
const nutritionEntry = {
id: generateId(),
date: new Date().toISOString(),
meals: [
{
type: 'breakfast',
foods: [
{
name: 'Oatmeal',
calories: 150,
macros: {
protein: 5,
carbs: 27,
fat: 3
},
quantity: 1,
unit: 'cup'
}
]
}
],
totalCalories: 0, // calculated
totalMacros: {
protein: 0,
carbs: 0,
fat: 0
},
waterIntake: 0, // ml
goals: {
calories: 2200,
protein: 165,
carbs: 275,
fat: 73
}
};
// Macro calculation and visualization
function calculateMacroPercentages(macros, totalCalories) {
const proteinCals = macros.protein * 4;
const carbCals = macros.carbs * 4;
const fatCals = macros.fat * 9;
return {
protein: (proteinCals / totalCalories) * 100,
carbs: (carbCals / totalCalories) * 100,
fat: (fatCals / totalCalories) * 100
};
}
// Chart.js integration for progress tracking
const progressChart = new Chart(ctx, {
type: 'line',
data: {
labels: dates,
datasets: [{
label: 'Weight Progress',
data: weightData,
borderColor: 'var(--accent-blue)',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
beginAtZero: false,
grid: {
color: 'var(--border-secondary)'
}
}
}
}
});
// Achievement tracking
const achievements = {
'first_workout': {
name: 'First Steps',
description: 'Complete your first workout',
icon: '🏃♂️',
unlocked: false
},
'week_streak': {
name: 'Week Warrior',
description: 'Work out 7 days in a row',
icon: '🔥',
unlocked: false
},
'pr_bench': {
name: 'Bench Beast',
description: 'Set a new bench press PR',
icon: '💪',
unlocked: false
}
};
// Data organization in Firestore
users/{userId}/
├── profile/
│ ├── name: string
│ ├── email: string
│ ├── age: number
│ ├── height: number
│ ├── currentWeight: number
│ └── goals: object
├── workouts/{workoutId}/
│ ├── date: timestamp
│ ├── exercises: array
│ ├── duration: number
│ └── notes: string
├── nutrition/{dateString}/
│ ├── meals: array
│ ├── totalCalories: number
│ ├── macros: object
│ └── waterIntake: number
└── progress/{dateString}/
├── weight: number
├── bodyFat: number
├── measurements: object
└── photos: array
// firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
match /workouts/{workoutId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /nutrition/{date} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /progress/{date} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
}
// Memoized components for performance
const WorkoutExercise = React.memo(({ exercise, onUpdate }) => {
const [sets, setSets] = React.useState(exercise.sets);
const handleSetUpdate = React.useCallback((setIndex, updates) => {
setSets(prev => prev.map((set, index) =>
index === setIndex ? { ...set, ...updates } : set
));
}, []);
return (
<div className="exercise-container">
{/* Exercise UI */}
</div>
);
});
// Efficient data caching strategy
const useWorkoutData = (userId) => {
const [workouts, setWorkouts] = React.useState([]);
const [loading, setLoading] = React.useState(true);
React.useEffect(() => {
const unsubscribe = firebase.firestore()
.collection('users')
.doc(userId)
.collection('workouts')
.orderBy('date', 'desc')
.limit(50)
.onSnapshot((snapshot) => {
const workoutData = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
setWorkouts(workoutData);
setLoading(false);
});
return unsubscribe;
}, [userId]);
return { workouts, loading };
};
/* Optimized touch targets */
.touch-target {
min-height: 44px;
min-width: 44px;
display: flex;
align-items: center;
justify-content: center;
-webkit-tap-highlight-color: transparent;
}
/* Smooth scrolling */
.scrollable-area {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* Mobile-first responsive design */
@media (max-width: 640px) {
.input-area {
width: 90vw;
}
.story-words.full-story {
height: calc(100vh - 60px);
padding: 20px;
font-size: 1em;
}
}
/* Larger screens */
@media (min-width: 1024px) {
.input-area {
max-width: min(70vw, 900px);
}
}
// Comprehensive keyboard support
document.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
// Focus management
handleTabNavigation(e);
} else if (e.key === 'Enter' || e.key === ' ') {
// Action activation
handleActionKeys(e);
} else if (e.key === 'Escape') {
// Modal dismissal
handleEscapeKey(e);
}
});
<!-- ARIA labels and roles -->
<button aria-label="Add new set"
aria-describedby="set-help-text"
role="button">
+
</button>
<div id="set-help-text" className="sr-only">
Click to add a new set to this exercise
</div>
// Data export to various formats
function exportWorkoutData(format = 'json') {
const data = {
exportDate: new Date().toISOString(),
user: userProfile,
workouts: allWorkouts,
nutrition: nutritionData,
progress: progressData
};
switch (format) {
case 'json':
return JSON.stringify(data, null, 2);
case 'csv':
return convertToCSV(data);
case 'pdf':
return generatePDF(data);
default:
return data;
}
}
// Error boundary for React components
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error('Hearts app error:', error, errorInfo);
// Log to error reporting service
}
render() {
if (this.state.hasError) {
return (
<div className="error-fallback">
<h2>Something went wrong</h2>
<button onClick={() => window.location.reload()}>
Reload app
</button>
</div>
);
}
return this.props.children;
}
}
Hearts represents a sophisticated fitness tracking platform that combines modern web technologies with thoughtful user experience design. The React-based architecture provides flexibility and performance, while the PWA features ensure accessibility across all devices. The comprehensive exercise database and nutrition tracking make it a complete fitness companion.
Technical Rating: 9.3/10