2007 lines
137 KiB
HTML
2007 lines
137 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" class="dark">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>HabitForge</title>
|
|
<!-- Tailwind CSS -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script>
|
|
tailwind.config = {
|
|
darkMode: 'class',
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
brand: {
|
|
50: '#f0f9ff',
|
|
100: '#e0f2fe',
|
|
500: '#0ea5e9',
|
|
600: '#0284c7',
|
|
900: '#0c4a6e',
|
|
}
|
|
},
|
|
fontFamily: {
|
|
sans: ['Inter', 'sans-serif'],
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<!-- Google Fonts -->
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
<!-- Font Awesome -->
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<!-- Custom Styles -->
|
|
<link rel="stylesheet" href="styles.css?v=3">
|
|
</head>
|
|
|
|
<body
|
|
class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 transition-colors duration-300 font-sans min-h-screen flex flex-col">
|
|
|
|
<!-- Header -->
|
|
<nav class="bg-white dark:bg-gray-800 shadow-lg border-b border-gray-200 dark:border-gray-700 z-50">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex justify-between h-16">
|
|
<div class="flex items-center">
|
|
<i class="fa-solid fa-fire text-brand-500 text-2xl mr-3 animate-pulse"></i>
|
|
<h1
|
|
class="text-2xl font-bold tracking-tight bg-gradient-to-r from-brand-500 to-purple-600 bg-clip-text text-transparent">
|
|
HabitForge</h1>
|
|
</div>
|
|
<div class="flex items-center space-x-4">
|
|
<button id="health-toggle-btn"
|
|
class="bg-white dark:bg-gray-700 text-gray-600 dark:text-gray-200 hover:text-brand-500 border border-gray-200 dark:border-gray-600 px-4 py-2 rounded-lg text-sm font-medium transition-all shadow-sm hover:shadow active:scale-95 flex items-center gap-2">
|
|
<i class="fas fa-heart-pulse text-red-500"></i> <span class="hidden sm:inline">Health</span>
|
|
</button>
|
|
<button id="theme-toggle"
|
|
class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-500 dark:text-gray-400 focus:outline-none transition-transform active:scale-95">
|
|
<i class="fas fa-moon dark:hidden"></i>
|
|
<i class="fas fa-sun hidden dark:block"></i>
|
|
</button>
|
|
<!-- stats-btn removed/hidden as per new design focus, or kept for legacy -->
|
|
<button id="export-btn"
|
|
class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-500 dark:text-gray-400 focus:outline-none transition-transform active:scale-95"
|
|
title="Export Data">
|
|
<i class="fas fa-file-export"></i>
|
|
</button>
|
|
<button id="add-challenge-btn"
|
|
class="bg-brand-600 hover:bg-brand-500 text-white px-4 py-2 rounded-lg text-sm font-medium transition-all shadow-md hover:shadow-lg active:scale-95 flex items-center">
|
|
<i class="fas fa-plus mr-2"></i> New Challenge
|
|
</button>
|
|
<button id="logout-btn"
|
|
class="p-2 ml-2 rounded-full hover:bg-red-50 dark:hover:bg-red-900/20 text-red-500 focus:outline-none transition-transform active:scale-95"
|
|
title="Logout">
|
|
<i class="fas fa-sign-out-alt"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Main Content -->
|
|
<main class="flex-grow max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 w-full">
|
|
<!-- Dashboard View (Habit Tracker) -->
|
|
<div id="dashboard-view" class="space-y-8 transition-opacity duration-300">
|
|
<!-- Stats Overview -->
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6 border border-gray-100 dark:border-gray-700 relative overflow-hidden group hover:border-brand-500 transition-colors">
|
|
<div class="absolute right-0 top-0 h-full w-1 bg-brand-500"></div>
|
|
<div class="flex justify-between items-start">
|
|
<div>
|
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Total Reps Today</p>
|
|
<h3 class="text-3xl font-bold mt-1" id="total-reps-today">0</h3>
|
|
</div>
|
|
<div class="p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg text-brand-500">
|
|
<i class="fas fa-dumbbell text-xl"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6 border border-gray-100 dark:border-gray-700 relative overflow-hidden group hover:border-green-500 transition-colors">
|
|
<div class="absolute right-0 top-0 h-full w-1 bg-green-500"></div>
|
|
<div class="flex justify-between items-start">
|
|
<div>
|
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Active Streak</p>
|
|
<h3 class="text-3xl font-bold mt-1" id="active-streak">0</h3>
|
|
</div>
|
|
<div class="p-3 bg-green-50 dark:bg-green-900/20 rounded-lg text-green-500">
|
|
<i class="fas fa-fire-flame-curved text-xl"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6 border border-gray-100 dark:border-gray-700 relative overflow-hidden group hover:border-purple-500 transition-colors">
|
|
<div class="absolute right-0 top-0 h-full w-1 bg-purple-500"></div>
|
|
<div class="flex justify-between items-start">
|
|
<div>
|
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Completion Rate</p>
|
|
<h3 class="text-3xl font-bold mt-1" id="completion-rate">0%</h3>
|
|
</div>
|
|
<div class="p-3 bg-purple-50 dark:bg-purple-900/20 rounded-lg text-purple-500">
|
|
<i class="fas fa-chart-line text-xl"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Achievements Section -->
|
|
<div id="achievements-section"
|
|
class="bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6 border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Achievements</h3>
|
|
<div id="badge-list" class="flex space-x-4 overflow-x-auto pb-2">
|
|
<!-- Badges injected by JS -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Challenges Grid -->
|
|
<div id="challenges-grid" class="grid grid-cols-1 gap-6">
|
|
<!-- Challenge Cards will be injected here -->
|
|
</div>
|
|
|
|
<!-- Empty State -->
|
|
<div id="empty-state" class="hidden text-center py-20">
|
|
<div
|
|
class="inline-flex items-center justify-center w-20 h-20 rounded-full bg-gray-100 dark:bg-gray-800 mb-6">
|
|
<i class="fas fa-clipboard-list text-4xl text-gray-400"></i>
|
|
</div>
|
|
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">No challenges yet</h3>
|
|
<p class="text-gray-500 dark:text-gray-400 max-w-sm mx-auto mb-6">Start your journey by creating your
|
|
first daily challenge.</p>
|
|
<button onclick="document.getElementById('add-challenge-btn').click()"
|
|
class="text-brand-600 hover:text-brand-500 font-medium">Create one now →</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Health Dashboard View -->
|
|
<div id="health-dashboard-view" class="hidden space-y-6">
|
|
<!-- Header: Sync & Tabs -->
|
|
<div class="flex flex-col gap-4">
|
|
<div class="flex flex-col md:flex-row justify-between items-center gap-4">
|
|
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">Health Dashboard</h2>
|
|
|
|
<div class="flex items-center gap-2">
|
|
<!-- Enhanced Date Navigator -->
|
|
<div
|
|
class="flex items-center bg-white dark:bg-gray-800 rounded-lg p-1 border border-gray-200 dark:border-gray-700 shadow-sm hover:border-brand-400 transition-all group">
|
|
<button id="date-prev-btn"
|
|
class="p-1.5 text-gray-500 hover:text-brand-600 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-md transition-colors">
|
|
<i class="fas fa-chevron-left text-xs"></i>
|
|
</button>
|
|
<button id="date-display"
|
|
class="px-3 text-xs font-semibold text-gray-700 dark:text-gray-200 min-w-[140px] text-center hover:text-brand-600 dark:hover:text-brand-400 transition-colors cursor-pointer flex items-center justify-center gap-1.5 group">
|
|
<i class="fas fa-calendar-alt text-[10px] opacity-50 group-hover:opacity-100"></i>
|
|
<span id="date-display-text">Today</span>
|
|
</button>
|
|
<button id="date-next-btn"
|
|
class="p-1.5 text-gray-500 hover:text-brand-600 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-md transition-colors">
|
|
<i class="fas fa-chevron-right text-xs"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-1 bg-gray-100 dark:bg-gray-800 p-1 rounded-lg">
|
|
<button
|
|
class="timeframe-btn px-3 py-1 rounded-md text-xs font-medium transition-all text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200"
|
|
data-period="day">Day</button>
|
|
<button
|
|
class="timeframe-btn px-3 py-1 rounded-md text-xs font-medium transition-all bg-white dark:bg-gray-700 shadow-sm text-brand-600 dark:text-brand-400"
|
|
data-period="week">Week</button>
|
|
<button
|
|
class="timeframe-btn px-3 py-1 rounded-md text-xs font-medium transition-all text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200"
|
|
data-period="month">Month</button>
|
|
</div>
|
|
<!-- Source Selector -->
|
|
<div id="source-selector-container"
|
|
class="hidden flex items-center gap-1 bg-gray-100 dark:bg-gray-800 p-1 rounded-lg">
|
|
<label for="health-source-select" class="text-xs text-gray-500 ml-2 mr-1"><i
|
|
class="fas fa-database"></i></label>
|
|
<select id="health-source-select"
|
|
class="bg-transparent text-xs font-medium text-gray-700 dark:text-gray-200 focus:outline-none cursor-pointer">
|
|
<option value="">Auto (Best)</option>
|
|
</select>
|
|
</div>
|
|
<!-- Single Source Label (shown when only 1 source) -->
|
|
<div id="source-label-container"
|
|
class="hidden flex items-center gap-1.5 px-3 py-1.5 bg-gray-100 dark:bg-gray-800 rounded-lg">
|
|
<i class="fas fa-database text-xs text-brand-500"></i>
|
|
<span id="source-name-display"
|
|
class="text-xs font-medium text-gray-700 dark:text-gray-200">--</span>
|
|
</div>
|
|
|
|
<!-- Sync Buttons Group -->
|
|
<!-- Sync Buttons Group Removed -->
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tabs -->
|
|
<div class="flex space-x-1 border-b border-gray-200 dark:border-gray-700 overflow-x-auto">
|
|
<button
|
|
class="health-tab-btn active-tab px-4 py-2 text-sm font-medium text-brand-600 border-b-2 border-brand-600 focus:outline-none transition-colors"
|
|
data-tab="overview">Overview</button>
|
|
<button
|
|
class="health-tab-btn px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 border-b-2 border-transparent hover:border-gray-300 dark:hover:border-gray-600 focus:outline-none transition-colors"
|
|
data-tab="workouts">Workouts</button>
|
|
<button
|
|
class="health-tab-btn px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 border-b-2 border-transparent hover:border-gray-300 dark:hover:border-gray-600 focus:outline-none transition-colors"
|
|
data-tab="readiness">Readiness</button>
|
|
<button
|
|
class="health-tab-btn px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 border-b-2 border-transparent hover:border-gray-300 dark:hover:border-gray-600 focus:outline-none transition-colors"
|
|
data-tab="sleep">Sleep</button>
|
|
<button
|
|
class="health-tab-btn px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 border-b-2 border-transparent hover:border-gray-300 dark:hover:border-gray-600 focus:outline-none transition-colors"
|
|
data-tab="exertion">Exertion</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab Content: Overview -->
|
|
<div id="tab-overview" class="health-tab-content space-y-6 animate-fade-in">
|
|
|
|
<!-- DAY VIEW -->
|
|
<div id="overview-day" class="period-view space-y-6">
|
|
<!-- Top Row: Activity Ring + Stats -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<!-- Activity Ring (DAY) -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700 flex flex-col items-center justify-center relative">
|
|
<h3 class="text-sm font-bold text-gray-500 dark:text-gray-400 absolute top-4 left-4">
|
|
Activity Rings</h3>
|
|
<div class="relative w-48 h-48 mt-4">
|
|
<canvas id="chart-rings"></canvas>
|
|
<div
|
|
class="absolute inset-0 flex flex-col items-center justify-center pointer-events-none">
|
|
<span class="text-xs text-gray-400">PAI</span>
|
|
<span class="text-2xl font-bold text-white" id="val-pai-ring">--</span>
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-3 gap-4 w-full mt-4 text-center">
|
|
<div>
|
|
<p class="text-xs text-blue-500 font-bold">Steps</p>
|
|
<p class="text-sm font-bold" id="ring-steps">--</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-green-500 font-bold">Calories</p>
|
|
<p class="text-sm font-bold" id="ring-cals">--</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-purple-500 font-bold">Distance</p>
|
|
<p class="text-sm font-bold" id="ring-distance">--</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Heart Rate Card with 24h curve -->
|
|
<div class="lg:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-start mb-4">
|
|
<div>
|
|
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400">Heart Rate</h3>
|
|
<p class="text-3xl font-bold text-gray-900 dark:text-white mt-1"
|
|
id="overview-hr">--
|
|
<span class="text-sm font-normal text-gray-400">bpm</span>
|
|
</p>
|
|
</div>
|
|
<div class="p-2 bg-red-50 dark:bg-red-900/20 rounded-lg text-red-500">
|
|
<i class="fas fa-heart-pulse"></i>
|
|
</div>
|
|
</div>
|
|
<div class="h-32"><canvas id="chart-mini-hr"></canvas></div>
|
|
<div class="flex justify-between text-xs text-gray-400 mt-2">
|
|
<span>Min: <span id="hr-min-day" class="text-blue-400 font-bold">--</span></span>
|
|
<span>Avg: <span id="hr-avg-day" class="text-green-400 font-bold">--</span></span>
|
|
<span>Max: <span id="hr-max-day" class="text-red-400 font-bold">--</span></span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sleep Summary -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-start mb-2">
|
|
<div>
|
|
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400">Sleep Score
|
|
</h3>
|
|
<div class="flex items-baseline gap-2 mt-1">
|
|
<p class="text-3xl font-bold text-gray-900 dark:text-white"
|
|
id="overview-sleep-score">--</p>
|
|
<span class="text-sm font-medium text-gray-500" id="overview-sleep-dur">--h
|
|
--m</span>
|
|
</div>
|
|
</div>
|
|
<div class="p-2 bg-purple-50 dark:bg-purple-900/20 rounded-lg text-purple-500">
|
|
<i class="fas fa-bed"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sleep Stages Stacked Bar -->
|
|
<div
|
|
class="w-full bg-gray-100 dark:bg-gray-700 rounded-full h-2.5 mt-3 flex overflow-hidden">
|
|
<div id="sleep-bar-deep" class="bg-indigo-600 h-full transition-all duration-500"
|
|
style="width: 0%" title="Deep Sleep"></div>
|
|
<div id="sleep-bar-rem" class="bg-purple-500 h-full transition-all duration-500"
|
|
style="width: 0%" title="REM Sleep"></div>
|
|
<div id="sleep-bar-light" class="bg-purple-300 h-full transition-all duration-500"
|
|
style="width: 0%" title="Light Sleep"></div>
|
|
</div>
|
|
|
|
<!-- Legend / Details -->
|
|
<div class="grid grid-cols-3 gap-1 mt-3 text-xs">
|
|
<div class="flex flex-col items-center">
|
|
<span class="text-gray-400 mb-0.5">Deep</span>
|
|
<div class="flex items-center gap-1.5">
|
|
<div class="w-1.5 h-1.5 rounded-full bg-indigo-600"></div>
|
|
<span class="font-bold text-gray-700 dark:text-gray-300"
|
|
id="val-deep-overview">--</span>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col items-center border-l dark:border-gray-700">
|
|
<span class="text-gray-400 mb-0.5">REM</span>
|
|
<div class="flex items-center gap-1.5">
|
|
<div class="w-1.5 h-1.5 rounded-full bg-purple-500"></div>
|
|
<span class="font-bold text-gray-700 dark:text-gray-300"
|
|
id="val-rem-overview">--</span>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col items-center border-l dark:border-gray-700">
|
|
<span class="text-gray-400 mb-0.5">Light</span>
|
|
<div class="flex items-center gap-1.5">
|
|
<div class="w-1.5 h-1.5 rounded-full bg-purple-300"></div>
|
|
<span class="font-bold text-gray-700 dark:text-gray-300"
|
|
id="val-light-overview">--</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Body Metrics -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<!-- Weight Widget -->
|
|
<div onclick="openMetricDetails('weight')"
|
|
class="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-8 shadow-xl border border-gray-700 cursor-pointer hover:scale-[1.02] transition-transform duration-300">
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<div class="p-2 bg-gray-700/50 rounded-lg"><i
|
|
class="fas fa-weight-scale text-gray-400 text-lg"></i></div>
|
|
<div>
|
|
<h3 class="text-white font-bold text-base uppercase tracking-wider">WEIGHT</h3>
|
|
<p class="text-gray-500 text-xs" id="weight-date">--</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center justify-center my-8">
|
|
<div class="relative w-64 h-40">
|
|
<canvas id="gauge-weight" class="absolute inset-0 w-full h-full"></canvas>
|
|
<div class="absolute inset-x-0 bottom-0 flex flex-col items-center pb-1">
|
|
<span class="text-5xl font-bold text-white leading-none"
|
|
id="val-weight-gauge">--</span>
|
|
<span class="text-sm text-cyan-400 uppercase tracking-wider mt-1 font-semibold"
|
|
id="weight-status">BALANCED</span>
|
|
<span class="text-xs text-gray-500 uppercase mt-0.5">WEIGHT(lbs)</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- BMI Widget -->
|
|
<div onclick="openMetricDetails('bmi')"
|
|
class="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-8 shadow-xl border border-gray-700 cursor-pointer hover:scale-[1.02] transition-transform duration-300">
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<div class="p-2 bg-gray-700/50 rounded-lg"><i
|
|
class="fas fa-chart-line text-gray-400 text-lg"></i></div>
|
|
<div>
|
|
<h3 class="text-white font-bold text-base uppercase tracking-wider">BMI</h3>
|
|
<p class="text-gray-500 text-xs" id="bmi-date">--</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center justify-center my-8">
|
|
<div class="relative w-64 h-40">
|
|
<canvas id="gauge-bmi" class="absolute inset-0 w-full h-full"></canvas>
|
|
<div class="absolute inset-x-0 bottom-0 flex flex-col items-center pb-1">
|
|
<span class="text-5xl font-bold text-white leading-none"
|
|
id="val-bmi-gauge">--</span>
|
|
<span class="text-sm text-blue-400 uppercase tracking-wider mt-1 font-semibold"
|
|
id="bmi-status">NORMAL</span>
|
|
<span class="text-xs text-gray-500 uppercase mt-0.5">BMI</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WEEK VIEW -->
|
|
<div id="overview-week" class="period-view hidden space-y-6">
|
|
<!-- Weekly PAI Bar Chart + Mini Rings -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Weekly Activity</h3>
|
|
<p class="text-sm text-gray-500">PAI Score per day</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-2xl font-bold text-orange-500" id="week-total-pai">--</p>
|
|
<p class="text-xs text-gray-400">Avg Weekly PAI</p>
|
|
</div>
|
|
</div>
|
|
<div class="h-64"><canvas id="chart-week-pai"></canvas></div>
|
|
|
|
<!-- Mini Rings Row -->
|
|
<div class="grid grid-cols-7 gap-2 mt-6 pt-4 border-t border-gray-100 dark:border-gray-700">
|
|
<div class="text-center" id="mini-ring-0">
|
|
<div
|
|
class="w-10 h-10 mx-auto rounded-full border-4 border-gray-200 dark:border-gray-700">
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-1">Mon</p>
|
|
</div>
|
|
<div class="text-center" id="mini-ring-1">
|
|
<div
|
|
class="w-10 h-10 mx-auto rounded-full border-4 border-gray-200 dark:border-gray-700">
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-1">Tue</p>
|
|
</div>
|
|
<div class="text-center" id="mini-ring-2">
|
|
<div
|
|
class="w-10 h-10 mx-auto rounded-full border-4 border-gray-200 dark:border-gray-700">
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-1">Wed</p>
|
|
</div>
|
|
<div class="text-center" id="mini-ring-3">
|
|
<div
|
|
class="w-10 h-10 mx-auto rounded-full border-4 border-gray-200 dark:border-gray-700">
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-1">Thu</p>
|
|
</div>
|
|
<div class="text-center" id="mini-ring-4">
|
|
<div
|
|
class="w-10 h-10 mx-auto rounded-full border-4 border-gray-200 dark:border-gray-700">
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-1">Fri</p>
|
|
</div>
|
|
<div class="text-center" id="mini-ring-5">
|
|
<div
|
|
class="w-10 h-10 mx-auto rounded-full border-4 border-gray-200 dark:border-gray-700">
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-1">Sat</p>
|
|
</div>
|
|
<div class="text-center" id="mini-ring-6">
|
|
<div
|
|
class="w-10 h-10 mx-auto rounded-full border-4 border-gray-200 dark:border-gray-700">
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-1">Sun</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Legend for Mini Rings -->
|
|
<div class="flex items-center justify-center gap-4 mt-4 text-xs text-gray-400">
|
|
<div class="flex items-center gap-1.5">
|
|
<div class="w-2 h-2 rounded-full border-2 border-green-500 bg-green-500/20"></div>
|
|
<span>Goal Met</span>
|
|
</div>
|
|
<div class="flex items-center gap-1.5">
|
|
<div class="w-2 h-2 rounded-full border-2 border-gray-600 bg-transparent"></div>
|
|
<span>Below Goal</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Weekly Stats Grid -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl p-5 text-white">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-shoe-prints"></i><span
|
|
class="text-sm opacity-80">Avg Steps</span></div>
|
|
<p class="text-2xl font-bold" id="week-avg-steps">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-red-500 to-red-600 rounded-xl p-5 text-white">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-fire"></i><span
|
|
class="text-sm opacity-80">Avg Calories</span></div>
|
|
<p class="text-2xl font-bold" id="week-avg-cals">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-purple-500 to-purple-600 rounded-xl p-5 text-white">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-bed"></i><span
|
|
class="text-sm opacity-80">Avg Sleep</span></div>
|
|
<p class="text-2xl font-bold" id="week-avg-sleep">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-green-500 to-green-600 rounded-xl p-5 text-white">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-heart"></i><span
|
|
class="text-sm opacity-80">Avg RHR</span></div>
|
|
<p class="text-2xl font-bold" id="week-avg-rhr">--</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MONTH VIEW -->
|
|
<div id="overview-month" class="period-view hidden space-y-6">
|
|
<!-- Activity Heatmap -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-6">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Activity Heatmap</h3>
|
|
<p class="text-sm text-gray-500">Daily activity intensity over 30 days</p>
|
|
</div>
|
|
<div class="flex items-center gap-4 text-sm">
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-green-500 font-bold" id="month-active-days">--</span>
|
|
<span class="text-gray-400">Active Days</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-gray-400 font-bold" id="month-rest-days">--</span>
|
|
<span class="text-gray-400">Rest Days</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Heatmap Calendar Grid -->
|
|
<div id="heatmap-container" class="grid grid-cols-7 gap-1">
|
|
<!-- Days will be injected by JS -->
|
|
</div>
|
|
|
|
<!-- Legend -->
|
|
<div class="flex items-center justify-center gap-2 mt-4 text-xs text-gray-400">
|
|
<span>Less</span>
|
|
<div class="w-4 h-4 rounded bg-gray-700"></div>
|
|
<div class="w-4 h-4 rounded bg-green-900"></div>
|
|
<div class="w-4 h-4 rounded bg-green-700"></div>
|
|
<div class="w-4 h-4 rounded bg-green-500"></div>
|
|
<div class="w-4 h-4 rounded bg-green-400"></div>
|
|
<span>More</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Monthly Trends -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Steps Trend</h3>
|
|
<div class="h-48"><canvas id="chart-month-steps"></canvas></div>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Sleep Duration Trend</h3>
|
|
<div class="h-48"><canvas id="chart-month-sleep"></canvas></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Tab Content: Readiness -->
|
|
<div id="tab-readiness" class="health-tab-content hidden space-y-6 animate-fade-in">
|
|
|
|
<!-- DAY VIEW - Score Gauge with Reasons -->
|
|
<div id="readiness-day" class="period-view space-y-6">
|
|
<div class="flex flex-col items-center justify-center py-8">
|
|
<div class="relative w-64 h-64">
|
|
<canvas id="gauge-readiness-split"></canvas>
|
|
<div class="absolute inset-0 flex flex-col items-center justify-center pointer-events-none">
|
|
<span class="text-5xl font-bold text-gray-900 dark:text-white"
|
|
id="readiness-score">--</span>
|
|
<span class="text-sm uppercase font-bold text-gray-400 mt-1">Ready</span>
|
|
</div>
|
|
</div>
|
|
<p class="mt-6 text-center max-w-lg text-gray-600 dark:text-gray-300 text-lg font-medium"
|
|
id="readiness-text">
|
|
Analyzing your recovery...
|
|
</p>
|
|
|
|
<!-- Subjective Input -->
|
|
<div
|
|
class="w-full max-w-md mt-8 p-5 bg-white dark:bg-gray-800/50 rounded-xl border border-gray-100 dark:border-gray-700 shadow-sm">
|
|
<div class="flex justify-between items-center mb-3">
|
|
<label class="text-sm font-bold text-gray-700 dark:text-gray-200">How do you feel
|
|
today?</label>
|
|
<span id="slider-val-display" class="text-xs font-bold text-brand-500">50%</span>
|
|
</div>
|
|
<input type="range" id="readiness-slider" min="1" max="100" value="50"
|
|
class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 accent-brand-500 h-range">
|
|
<div class="flex justify-between text-xs text-gray-400 mt-2 font-medium">
|
|
<span>😴 Tired</span>
|
|
<span>⚡ Energetic</span>
|
|
</div>
|
|
<div class="mt-4 flex flew-row gap-2 justify-end">
|
|
<button onclick="toggleTagsInput()"
|
|
class="text-gray-400 hover:text-brand-500 transition-colors text-sm mr-auto"
|
|
title="Add tags"><i class="fas fa-tag"></i> Add Tags</button>
|
|
<button id="save-context-btn"
|
|
class="bg-brand-600 hover:bg-brand-500 text-white px-4 py-1.5 rounded-lg text-sm font-medium shadow-sm active:scale-95 transition-all">Update
|
|
Feel</button>
|
|
</div>
|
|
<!-- Hidden Tags Input -->
|
|
<div id="tags-input-container"
|
|
class="hidden mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
|
|
<label class="text-xs text-gray-500 mb-1 block">Context Tags (comma separated)</label>
|
|
<input type="text" id="context-tags-input" placeholder="e.g. Stress, Alcohol, Travel"
|
|
class="w-full bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded px-2 py-1 text-sm text-gray-800 dark:text-white focus:outline-none focus:border-brand-500">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Why This Score -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Why This Score?</h3>
|
|
<div id="readiness-factors" class="space-y-3">
|
|
<div class="flex items-center gap-3 p-3 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
|
<i class="fas fa-check-circle text-green-500"></i>
|
|
<span class="text-gray-700 dark:text-gray-300">Good sleep duration (7h+)</span>
|
|
</div>
|
|
<div class="flex items-center gap-3 p-3 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
|
<i class="fas fa-check-circle text-green-500"></i>
|
|
<span class="text-gray-700 dark:text-gray-300">Low resting heart rate</span>
|
|
</div>
|
|
<div class="flex items-center gap-3 p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg">
|
|
<i class="fas fa-minus-circle text-yellow-500"></i>
|
|
<span class="text-gray-700 dark:text-gray-300">HRV slightly below baseline</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Contributing Factors -->
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-5 shadow-sm border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Resting HR</h4>
|
|
<div class="flex items-end gap-2">
|
|
<span class="text-2xl font-bold text-gray-900 dark:text-white" id="val-rhr">--</span>
|
|
<span class="text-xs text-green-500 mb-1"><i class="fas fa-arrow-down"></i>
|
|
Optimal</span>
|
|
</div>
|
|
<div class="h-20 mt-2"><canvas id="chart-rhr"></canvas></div>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-5 shadow-sm border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">HRV (ms)</h4>
|
|
<div class="flex items-end gap-2">
|
|
<span class="text-2xl font-bold text-gray-900 dark:text-white" id="val-hrv">--</span>
|
|
<span class="text-xs text-brand-500 mb-1">Balanced</span>
|
|
</div>
|
|
<div class="h-20 mt-2"><canvas id="chart-hrv"></canvas></div>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-5 shadow-sm border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Sleep Balance</h4>
|
|
<div class="flex items-end gap-2">
|
|
<span class="text-2xl font-bold text-gray-900 dark:text-white"
|
|
id="val-sleep-balance">Good</span>
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-2">Consistent sleep duration over last week.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WEEK VIEW - Recovery vs Strain -->
|
|
<div id="readiness-week" class="period-view hidden space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Recovery vs Training Load</h3>
|
|
<p class="text-sm text-gray-500 mb-4">Track if your recovery keeps up with your effort</p>
|
|
<div class="h-72"><canvas id="chart-recovery-strain"></canvas></div>
|
|
<div class="flex justify-center gap-6 mt-4">
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-3 h-3 rounded-full bg-green-500"></div><span
|
|
class="text-sm text-gray-500">Recovery</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-3 h-3 rounded-full bg-red-500"></div><span
|
|
class="text-sm text-gray-500">Training Load</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Avg Recovery</p>
|
|
<p class="text-2xl font-bold" id="week-avg-recovery">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-red-500 to-rose-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Avg Strain</p>
|
|
<p class="text-2xl font-bold" id="week-avg-strain">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-blue-500 to-cyan-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Best Day</p>
|
|
<p class="text-2xl font-bold" id="week-best-day">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-purple-500 to-violet-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Balance</p>
|
|
<p class="text-2xl font-bold" id="week-balance-status">Good</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MONTH VIEW - HRV Trend (Overtraining Risk) -->
|
|
<div id="readiness-month" class="period-view hidden space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">HRV Trend Analysis</h3>
|
|
<p class="text-sm text-gray-500">Detect early signs of fatigue or overtraining</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-sm text-gray-400">30-Day Average</p>
|
|
<p class="text-2xl font-bold text-purple-500" id="month-hrv-avg">-- ms</p>
|
|
</div>
|
|
</div>
|
|
<div class="h-64"><canvas id="chart-hrv-trend"></canvas></div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Trend Direction</h4>
|
|
<div class="flex items-center gap-2">
|
|
<i class="fas fa-arrow-trend-up text-green-500 text-2xl" id="hrv-trend-icon"></i>
|
|
<span class="text-xl font-bold text-gray-900 dark:text-white"
|
|
id="hrv-trend-text">Improving</span>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Overtraining Risk</h4>
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-3">
|
|
<div class="bg-green-500 h-3 rounded-full" style="width: 20%" id="overtraining-bar">
|
|
</div>
|
|
</div>
|
|
<span class="text-sm font-bold text-green-500" id="overtraining-level">Low</span>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Recommendation</h4>
|
|
<p class="text-gray-600 dark:text-gray-300 text-sm" id="readiness-recommendation">Continue
|
|
your current training load. Your body is adapting well.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Tab Content: Sleep -->
|
|
<div id="tab-sleep" class="health-tab-content hidden space-y-6 animate-fade-in">
|
|
|
|
<!-- DAY VIEW - Hypnogram + Sleep Stages -->
|
|
<div id="sleep-day" class="period-view space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Sleep Architecture</h3>
|
|
<div class="text-right">
|
|
<p class="text-sm text-gray-400">Total Sleep</p>
|
|
<p class="text-2xl font-bold text-purple-500" id="sleep-day-total">--</p>
|
|
</div>
|
|
</div>
|
|
<!-- Hypnogram - Time-based view -->
|
|
<div class="h-32 bg-gray-900/50 rounded-lg p-4 mb-4">
|
|
<canvas id="chart-hypnogram"></canvas>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-2 text-xs text-gray-400">
|
|
<span id="sleep-start-time">Bedtime: --:--</span>
|
|
<span class="text-right" id="sleep-end-time">Wake: --:--</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sleep Stages breakdown -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="bg-purple-600/20 border border-purple-600/30 rounded-xl p-4 text-center">
|
|
<div
|
|
class="w-8 h-8 mx-auto rounded-full bg-purple-600 flex items-center justify-center mb-2">
|
|
<i class="fas fa-moon text-white text-sm"></i>
|
|
</div>
|
|
<p class="text-xs text-gray-400">Deep</p>
|
|
<p class="text-xl font-bold text-purple-500" id="val-deep">--</p>
|
|
</div>
|
|
<div class="bg-blue-400/20 border border-blue-400/30 rounded-xl p-4 text-center">
|
|
<div class="w-8 h-8 mx-auto rounded-full bg-blue-400 flex items-center justify-center mb-2">
|
|
<i class="fas fa-cloud text-white text-sm"></i>
|
|
</div>
|
|
<p class="text-xs text-gray-400">Light</p>
|
|
<p class="text-xl font-bold text-blue-400" id="val-light">--</p>
|
|
</div>
|
|
<div class="bg-yellow-400/20 border border-yellow-400/30 rounded-xl p-4 text-center">
|
|
<div
|
|
class="w-8 h-8 mx-auto rounded-full bg-yellow-400 flex items-center justify-center mb-2">
|
|
<i class="fas fa-brain text-white text-sm"></i>
|
|
</div>
|
|
<p class="text-xs text-gray-400">REM</p>
|
|
<p class="text-xl font-bold text-yellow-400" id="val-rem">--</p>
|
|
</div>
|
|
<div class="bg-gray-400/20 border border-gray-400/30 rounded-xl p-4 text-center">
|
|
<div class="w-8 h-8 mx-auto rounded-full bg-gray-400 flex items-center justify-center mb-2">
|
|
<i class="fas fa-eye text-white text-sm"></i>
|
|
</div>
|
|
<p class="text-xs text-gray-400">Awake</p>
|
|
<p class="text-xl font-bold text-gray-400" id="val-awake">--</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sleep metrics -->
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-5 shadow-sm border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500">Sleep Quality</h4>
|
|
<p class="text-2xl font-bold mt-1 text-green-500" id="sleep-quality-score">--</p>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-5 shadow-sm border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500">Avg HR (Sleep)</h4>
|
|
<p class="text-2xl font-bold mt-1 text-gray-900 dark:text-white" id="val-sleep-hr">--</p>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-5 shadow-sm border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500">Sleep Efficiency</h4>
|
|
<p class="text-2xl font-bold mt-1 text-purple-500" id="sleep-efficiency">--%</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WEEK VIEW - Sleep Regularity (Range Bars) -->
|
|
<div id="sleep-week" class="period-view hidden space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Sleep Schedule</h3>
|
|
<p class="text-sm text-gray-500">Bedtime and wake time consistency</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-sm text-gray-400">Regularity</p>
|
|
<p class="text-2xl font-bold text-green-500" id="sleep-regularity-score">High</p>
|
|
</div>
|
|
</div>
|
|
<div class="h-64"><canvas id="chart-sleep-schedule"></canvas></div>
|
|
<div class="flex justify-center gap-4 mt-4 text-sm text-gray-500">
|
|
<span><i class="fas fa-bed text-purple-500 mr-1"></i> Bedtime</span>
|
|
<span><i class="fas fa-sun text-yellow-500 mr-1"></i> Wake time</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="bg-gradient-to-br from-purple-500 to-violet-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Avg Duration</p>
|
|
<p class="text-2xl font-bold" id="week-avg-duration">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-blue-500 to-cyan-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Avg Bedtime</p>
|
|
<p class="text-2xl font-bold" id="week-avg-bedtime">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-yellow-500 to-orange-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Avg Wake</p>
|
|
<p class="text-2xl font-bold" id="week-avg-wake">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-5 text-white">
|
|
<p class="text-sm opacity-80">Best Night</p>
|
|
<p class="text-2xl font-bold" id="week-best-night">--</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MONTH VIEW - Sleep Debt Tracker -->
|
|
<div id="sleep-month" class="period-view hidden space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Sleep Duration Trend</h3>
|
|
<p class="text-sm text-gray-500">Daily sleep vs 8h goal</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-sm text-gray-400">Sleep Debt</p>
|
|
<p class="text-2xl font-bold" id="month-sleep-debt"><span class="text-red-500">-2h
|
|
30m</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="h-64"><canvas id="chart-sleep-debt"></canvas></div>
|
|
<div class="flex justify-center gap-4 mt-4 text-xs">
|
|
<span><span class="inline-block w-3 h-3 rounded bg-red-500 mr-1"></span>Below 6h</span>
|
|
<span><span class="inline-block w-3 h-3 rounded bg-yellow-500 mr-1"></span>6-7h</span>
|
|
<span><span class="inline-block w-3 h-3 rounded bg-green-500 mr-1"></span>7h+</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Nights Below Target</h4>
|
|
<p class="text-3xl font-bold text-red-500" id="month-nights-below">--</p>
|
|
<p class="text-xs text-gray-400 mt-1">out of 30 nights</p>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Monthly Average</h4>
|
|
<p class="text-3xl font-bold text-purple-500" id="month-avg-sleep">--</p>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Trend</h4>
|
|
<div class="flex items-center gap-2">
|
|
<i class="fas fa-arrow-trend-up text-green-500 text-2xl" id="sleep-trend-icon"></i>
|
|
<span class="text-xl font-bold text-gray-900 dark:text-white"
|
|
id="sleep-trend-text">Improving</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Tab Content: Exertion -->
|
|
<div id="tab-exertion" class="health-tab-content hidden space-y-6 animate-fade-in">
|
|
|
|
<!-- DAY VIEW - HR Zones -->
|
|
<div id="exertion-day" class="period-view space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Heart Rate Zones</h3>
|
|
<p class="text-sm text-gray-500">Time spent in each intensity zone today</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-sm text-gray-400">Today's PAI</p>
|
|
<p class="text-2xl font-bold text-orange-500" id="val-exertion-pai">--</p>
|
|
</div>
|
|
</div>
|
|
<div class="h-48"><canvas id="chart-hr-zones"></canvas></div>
|
|
</div>
|
|
|
|
<!-- Zone breakdown -->
|
|
<div class="grid grid-cols-5 gap-2">
|
|
<div class="bg-gray-100 dark:bg-gray-700 rounded-lg p-3 text-center">
|
|
<div class="w-full h-2 rounded-full bg-gray-400 mb-2"></div>
|
|
<p class="text-xs text-gray-500">Zone 1</p>
|
|
<p class="text-sm font-bold text-gray-900 dark:text-white" id="zone1-time">--</p>
|
|
</div>
|
|
<div class="bg-blue-50 dark:bg-blue-900/20 rounded-lg p-3 text-center">
|
|
<div class="w-full h-2 rounded-full bg-blue-400 mb-2"></div>
|
|
<p class="text-xs text-blue-500">Zone 2</p>
|
|
<p class="text-sm font-bold text-blue-600" id="zone2-time">--</p>
|
|
</div>
|
|
<div class="bg-green-50 dark:bg-green-900/20 rounded-lg p-3 text-center">
|
|
<div class="w-full h-2 rounded-full bg-green-400 mb-2"></div>
|
|
<p class="text-xs text-green-500">Zone 3</p>
|
|
<p class="text-sm font-bold text-green-600" id="zone3-time">--</p>
|
|
</div>
|
|
<div class="bg-orange-50 dark:bg-orange-900/20 rounded-lg p-3 text-center">
|
|
<div class="w-full h-2 rounded-full bg-orange-400 mb-2"></div>
|
|
<p class="text-xs text-orange-500">Zone 4</p>
|
|
<p class="text-sm font-bold text-orange-600" id="zone4-time">--</p>
|
|
</div>
|
|
<div class="bg-red-50 dark:bg-red-900/20 rounded-lg p-3 text-center">
|
|
<div class="w-full h-2 rounded-full bg-red-500 mb-2"></div>
|
|
<p class="text-xs text-red-500">Zone 5</p>
|
|
<p class="text-sm font-bold text-red-600" id="zone5-time">--</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Daily Suggestion -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Daily Suggestion</h3>
|
|
<div
|
|
class="bg-blue-50 dark:bg-blue-900/20 p-4 rounded-xl border border-blue-100 dark:border-blue-800">
|
|
<p class="text-brand-700 dark:text-brand-300 font-medium"><i
|
|
class="fas fa-info-circle mr-2"></i> Moderate Activity Recommended</p>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 mt-2">Based on your readiness score,
|
|
today is a good day for a 30-minute steady run or a moderate gym session.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WEEK VIEW - 7-Day Load Gauge -->
|
|
<div id="exertion-week" class="period-view hidden space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Weekly Training Load</h3>
|
|
|
|
<!-- Load Gauge -->
|
|
<div class="flex items-center justify-center py-8">
|
|
<div class="relative w-64 h-32">
|
|
<canvas id="chart-weekly-load-gauge"></canvas>
|
|
<div class="absolute inset-x-0 bottom-0 text-center">
|
|
<p class="text-3xl font-bold text-orange-500" id="weekly-load-value">--</p>
|
|
<p class="text-sm text-gray-400">Weekly PAI</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Load zones -->
|
|
<div class="flex justify-between text-xs text-gray-400 px-4 mb-4">
|
|
<span>Under</span>
|
|
<span class="text-green-500 font-bold">Optimal</span>
|
|
<span>Over</span>
|
|
</div>
|
|
<div class="h-3 rounded-full bg-gradient-to-r from-blue-400 via-green-400 to-red-400 relative">
|
|
<div class="absolute top-0 w-1 h-full bg-white rounded-full shadow" style="left: 50%"
|
|
id="load-indicator"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Daily PAI Breakdown</h3>
|
|
<div class="h-48"><canvas id="chart-exertion"></canvas></div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-3 gap-4">
|
|
<div class="bg-gradient-to-br from-orange-500 to-red-600 rounded-xl p-5 text-white text-center">
|
|
<p class="text-sm opacity-80">Total PAI</p>
|
|
<p class="text-3xl font-bold" id="week-total-exertion">--</p>
|
|
</div>
|
|
<div
|
|
class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-5 text-white text-center">
|
|
<p class="text-sm opacity-80">Goal Progress</p>
|
|
<p class="text-3xl font-bold" id="week-goal-progress">--%</p>
|
|
</div>
|
|
<div
|
|
class="bg-gradient-to-br from-purple-500 to-violet-600 rounded-xl p-5 text-white text-center">
|
|
<p class="text-sm opacity-80">Status</p>
|
|
<p class="text-2xl font-bold" id="week-load-status">Good</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MONTH VIEW - Acute/Chronic Load Ratio -->
|
|
<div id="exertion-month" class="period-view hidden space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Training Load Ratio</h3>
|
|
<p class="text-sm text-gray-500">Acute (7d) vs Chronic (28d) load - injury prevention
|
|
</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-sm text-gray-400">ACWR</p>
|
|
<p class="text-2xl font-bold" id="acwr-value"><span class="text-green-500">0.95</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="h-64"><canvas id="chart-acwr"></canvas></div>
|
|
|
|
<!-- Safe zone indicator -->
|
|
<div
|
|
class="mt-4 p-4 bg-green-50 dark:bg-green-900/20 rounded-lg border border-green-200 dark:border-green-800">
|
|
<p class="text-sm text-green-700 dark:text-green-300" id="acwr-message">
|
|
<i class="fas fa-shield-check mr-2"></i>
|
|
Your training load is in the <strong>safe zone</strong>. Low injury risk.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Acute Load (7d)</h4>
|
|
<p class="text-3xl font-bold text-blue-500" id="acute-load">--</p>
|
|
<p class="text-xs text-gray-400">This week's intensity</p>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Chronic Load (28d)</h4>
|
|
<p class="text-3xl font-bold text-purple-500" id="chronic-load">--</p>
|
|
<p class="text-xs text-gray-400">4-week average</p>
|
|
</div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h4 class="text-sm font-bold text-gray-500 mb-2">Recommendation</h4>
|
|
<p class="text-gray-600 dark:text-gray-300 text-sm" id="load-recommendation">Maintain
|
|
current load. Your fitness is building safely.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Tab Content: Workouts -->
|
|
<div id="tab-workouts" class="health-tab-content hidden space-y-6 animate-fade-in">
|
|
|
|
<!-- DAY VIEW - Timeline of sessions -->
|
|
<div id="workouts-day" class="period-view space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Today's Activities</h3>
|
|
<div id="workout-timeline" class="space-y-4">
|
|
<!-- Timeline items injected by JS -->
|
|
<div class="text-center text-gray-400 py-8">
|
|
<i class="fas fa-calendar-day text-4xl mb-2"></i>
|
|
<p>No workouts recorded today</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Daily summary -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="bg-gradient-to-br from-orange-500 to-red-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-dumbbell"></i><span
|
|
class="text-sm opacity-80">Sessions</span></div>
|
|
<p class="text-2xl font-bold" id="day-workout-count">0</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-blue-500 to-cyan-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-clock"></i><span
|
|
class="text-sm opacity-80">Duration</span></div>
|
|
<p class="text-2xl font-bold" id="day-workout-duration">0m</p>
|
|
</div>
|
|
<div
|
|
class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-route"></i><span
|
|
class="text-sm opacity-80">Distance</span></div>
|
|
<p class="text-2xl font-bold" id="day-workout-distance">0 km</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-purple-500 to-pink-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-2 mb-2"><i class="fas fa-fire"></i><span
|
|
class="text-sm opacity-80">Calories</span></div>
|
|
<p class="text-2xl font-bold" id="day-workout-calories">0</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WEEK VIEW - Distribution + Charts -->
|
|
<div id="workouts-week" class="period-view hidden space-y-6">
|
|
<!-- Summary Cards -->
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
<div class="bg-gradient-to-br from-orange-500 to-red-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-3 mb-2">
|
|
<i class="fas fa-fire-flame-curved text-xl"></i>
|
|
<span class="text-sm font-medium opacity-90">Total Workouts</span>
|
|
</div>
|
|
<p class="text-3xl font-bold" id="workout-total">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-blue-500 to-cyan-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-3 mb-2">
|
|
<i class="fas fa-clock text-xl"></i>
|
|
<span class="text-sm font-medium opacity-90">Total Duration</span>
|
|
</div>
|
|
<p class="text-3xl font-bold" id="workout-duration">--</p>
|
|
</div>
|
|
<div
|
|
class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-3 mb-2">
|
|
<i class="fas fa-route text-xl"></i>
|
|
<span class="text-sm font-medium opacity-90">Total Distance</span>
|
|
</div>
|
|
<p class="text-3xl font-bold" id="workout-distance">--</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-purple-500 to-pink-600 rounded-xl p-5 text-white shadow-lg">
|
|
<div class="flex items-center gap-3 mb-2">
|
|
<i class="fas fa-fire text-xl"></i>
|
|
<span class="text-sm font-medium opacity-90">Calories Burned</span>
|
|
</div>
|
|
<p class="text-3xl font-bold" id="workout-calories">--</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Charts -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Activity Breakdown</h3>
|
|
<div class="h-64"><canvas id="chart-workout-types"></canvas></div>
|
|
</div>
|
|
<div
|
|
class="lg:col-span-2 bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Weekly Activity</h3>
|
|
<div class="h-64"><canvas id="chart-workout-weekly"></canvas></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Intensity Distribution -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Intensity Distribution</h3>
|
|
<div class="grid grid-cols-3 gap-4">
|
|
<div class="text-center p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
|
<p class="text-2xl font-bold text-blue-500" id="week-low-intensity">--%</p>
|
|
<p class="text-sm text-gray-500">Low (Zone 1-2)</p>
|
|
</div>
|
|
<div class="text-center p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
|
<p class="text-2xl font-bold text-green-500" id="week-mod-intensity">--%</p>
|
|
<p class="text-sm text-gray-500">Moderate (Zone 3)</p>
|
|
</div>
|
|
<div class="text-center p-4 bg-red-50 dark:bg-red-900/20 rounded-lg">
|
|
<p class="text-2xl font-bold text-red-500" id="week-high-intensity">--%</p>
|
|
<p class="text-sm text-gray-500">High (Zone 4-5)</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Workouts List -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-100 dark:border-gray-700 overflow-hidden">
|
|
<div
|
|
class="p-5 border-b border-gray-100 dark:border-gray-700 flex justify-between items-center">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Recent Workouts</h3>
|
|
<select id="workout-filter"
|
|
class="text-sm px-3 py-1.5 rounded-lg border border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200">
|
|
<option value="">All Types</option>
|
|
<option value="Running">Running</option>
|
|
<option value="Walking">Walking</option>
|
|
<option value="Cycling">Cycling</option>
|
|
<option value="Free Training">Free Training</option>
|
|
</select>
|
|
</div>
|
|
<div id="workouts-list"
|
|
class="divide-y divide-gray-100 dark:divide-gray-700 max-h-96 overflow-y-auto custom-scrollbar">
|
|
<div class="p-8 text-center text-gray-400">
|
|
<i class="fas fa-spinner fa-spin text-2xl mb-2"></i>
|
|
<p>Loading workouts...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MONTH VIEW - Cumulative Volume -->
|
|
<div id="workouts-month" class="period-view hidden space-y-6">
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white">Cumulative Training Volume
|
|
</h3>
|
|
<p class="text-sm text-gray-500">Total hours/kilometers accumulated this month</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-sm text-gray-400">Monthly Total</p>
|
|
<p class="text-2xl font-bold text-green-500" id="month-total-volume">-- hrs</p>
|
|
</div>
|
|
</div>
|
|
<div class="h-64"><canvas id="chart-cumulative-volume"></canvas></div>
|
|
<div class="flex justify-center gap-4 mt-4 text-sm">
|
|
<span><span class="inline-block w-3 h-3 rounded bg-blue-500 mr-1"></span>This Month</span>
|
|
<span><span class="inline-block w-3 h-3 rounded bg-gray-400 mr-1"></span>Last Month</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
<div class="bg-gradient-to-br from-blue-500 to-cyan-600 rounded-xl p-5 text-white shadow-lg">
|
|
<p class="text-sm opacity-80">Total Sessions</p>
|
|
<p class="text-3xl font-bold" id="month-total-sessions">--</p>
|
|
</div>
|
|
<div
|
|
class="bg-gradient-to-br from-green-500 to-emerald-600 rounded-xl p-5 text-white shadow-lg">
|
|
<p class="text-sm opacity-80">Total Distance</p>
|
|
<p class="text-3xl font-bold" id="month-total-distance">-- km</p>
|
|
</div>
|
|
<div class="bg-gradient-to-br from-orange-500 to-red-600 rounded-xl p-5 text-white shadow-lg">
|
|
<p class="text-sm opacity-80">Total Calories</p>
|
|
<p class="text-3xl font-bold" id="month-total-calories">--</p>
|
|
</div>
|
|
<div
|
|
class="bg-gradient-to-br from-purple-500 to-violet-600 rounded-xl p-5 text-white shadow-lg">
|
|
<p class="text-sm opacity-80">vs Last Month</p>
|
|
<p class="text-2xl font-bold" id="month-vs-last"><i class="fas fa-arrow-up"></i> +12%</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Monthly Activity Calendar -->
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg border border-gray-100 dark:border-gray-700">
|
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Activity Calendar</h3>
|
|
<div id="workout-calendar" class="grid grid-cols-7 gap-1">
|
|
<!-- Calendar cells injected by JS -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Metric Details Modal -->
|
|
<div id="metric-details-modal"
|
|
class="fixed inset-0 z-50 flex items-center justify-center invisible opacity-0 transition-all duration-300">
|
|
<div class="absolute inset-0 bg-black/80 backdrop-blur-sm" id="metric-modal-backdrop"></div>
|
|
<div
|
|
class="bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl w-full max-w-2xl mx-4 transform scale-95 transition-all duration-300 relative z-10 overflow-hidden flex flex-col max-h-[90vh] border border-gray-700">
|
|
<!-- Header -->
|
|
<div class="p-6 border-b border-gray-800 flex justify-between items-center flex-shrink-0">
|
|
<div class="flex items-center gap-3">
|
|
<button id="metric-back-btn"
|
|
class="p-2 hover:bg-gray-800 rounded-lg transition-colors text-gray-400 hover:text-white">
|
|
<i class="fas fa-arrow-left"></i>
|
|
</button>
|
|
<div>
|
|
<h2 class="text-2xl font-bold text-white uppercase tracking-wider" id="metric-title">
|
|
WEIGHT
|
|
</h2>
|
|
<button id="metric-add-btn"
|
|
class="text-xs text-gray-400 hover:text-brand-400 transition-colors mt-1 flex items-center gap-1">
|
|
<i class="fas fa-plus"></i> Add Entry
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<button id="close-metric-modal-btn"
|
|
class="text-gray-400 hover:text-white transition-colors p-2 hover:bg-gray-800 rounded-lg">
|
|
<i class="fas fa-times text-xl"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Period Selector -->
|
|
<!-- Period Selector -->
|
|
<div
|
|
class="px-6 py-4 bg-gray-900/50 border-b border-gray-800 flex-shrink-0 flex items-center justify-between">
|
|
<button id="metric-prev-btn" class="p-2 text-gray-400 hover:text-white transition-colors">
|
|
<i class="fas fa-chevron-left"></i>
|
|
</button>
|
|
|
|
<div class="flex items-center gap-2 bg-gray-800/50 p-1 rounded-lg w-fit">
|
|
<button
|
|
class="metric-period-btn px-4 py-2 rounded-md text-sm font-medium transition-all bg-brand-600 text-white"
|
|
data-period="recent">Recent</button>
|
|
<button
|
|
class="metric-period-btn px-4 py-2 rounded-md text-sm font-medium transition-all text-gray-400 hover:text-white"
|
|
data-period="week">Week</button>
|
|
<button
|
|
class="metric-period-btn px-4 py-2 rounded-md text-sm font-medium transition-all text-gray-400 hover:text-white"
|
|
data-period="month">Month</button>
|
|
<button
|
|
class="metric-period-btn px-4 py-2 rounded-md text-sm font-medium transition-all text-gray-400 hover:text-white"
|
|
data-period="year">Year</button>
|
|
</div>
|
|
|
|
<button id="metric-next-btn" class="p-2 text-gray-400 hover:text-white transition-colors">
|
|
<i class="fas fa-chevron-right"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="p-6 overflow-y-auto custom-scrollbar flex-1">
|
|
<div id="metric-chart-view">
|
|
<!-- Current Value Display -->
|
|
<div class="text-center mb-6">
|
|
<div class="text-6xl font-bold text-white mb-2" id="metric-current-value">--</div>
|
|
<div class="text-sm text-gray-400" id="metric-current-date">--</div>
|
|
</div>
|
|
|
|
<!-- Chart -->
|
|
<div class="bg-gray-800/30 rounded-xl p-4 mb-6 border border-gray-800">
|
|
<div class="h-64">
|
|
<canvas id="metric-history-chart"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Summary Stats -->
|
|
<div id="metric-summary" class="bg-gray-800/30 rounded-xl p-5 border border-gray-800 mb-6">
|
|
<h3 class="text-white font-bold mb-4 text-sm uppercase tracking-wider">Summary</h3>
|
|
<div class="grid grid-cols-3 gap-4">
|
|
<div>
|
|
<p class="text-gray-400 text-xs mb-1">Avg.</p>
|
|
<p class="text-white font-bold text-lg" id="metric-avg">--</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-gray-400 text-xs mb-1">Maximum</p>
|
|
<p class="text-white font-bold text-lg" id="metric-max">--</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-gray-400 text-xs mb-1">Min</p>
|
|
<p class="text-white font-bold text-lg" id="metric-min">--</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Trends (for Weight) -->
|
|
<div id="metric-trends"
|
|
class="hidden bg-gray-800/30 rounded-xl p-5 border border-gray-800 mb-6">
|
|
<h3 class="text-white font-bold mb-4 text-sm uppercase tracking-wider">Weight Trends</h3>
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="text-red-500">
|
|
<i class="fas fa-arrow-up"></i>
|
|
<span class="font-bold ml-1" id="trend-progress">--</span>
|
|
</div>
|
|
<span class="text-xs text-gray-400">Progress</span>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<div class="text-green-500">
|
|
<i class="fas fa-arrow-down"></i>
|
|
<span class="font-bold ml-1" id="trend-comparison">--</span>
|
|
</div>
|
|
<span class="text-xs text-gray-400">Comparison</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- BMI Info (for BMI) -->
|
|
<div id="metric-bmi-info" class="hidden bg-gray-800/30 rounded-xl p-5 border border-gray-800">
|
|
<h3 class="text-white font-bold mb-3 text-sm uppercase tracking-wider">BMI Information</h3>
|
|
<p class="text-xs text-gray-400 leading-relaxed">
|
|
BMI: weight (kg)/height (m)²
|
|
</p>
|
|
<p class="text-xs text-gray-400 mt-3 leading-relaxed">
|
|
You can't judge if you're 'obese' just by BMI value. People can have more fat than
|
|
muscle
|
|
with normal BMI and still classify as obese.
|
|
</p>
|
|
<div class="mt-4 pt-4 border-t border-gray-700">
|
|
<p class="text-xs text-gray-500 mb-2">Ideal weight: <span class="text-white font-bold"
|
|
id="ideal-weight">--</span></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- View: History List -->
|
|
<div id="metric-list-view" class="hidden space-y-4">
|
|
<div class="flex justify-between items-center mb-2 px-2">
|
|
<h3 class="text-white font-bold text-sm uppercase tracking-wider">History Log</h3>
|
|
<span class="text-xs text-gray-500" id="history-entry-count">0 entries</span>
|
|
</div>
|
|
<div class="bg-gray-800/30 rounded-xl border border-gray-800 overflow-hidden">
|
|
<table class="w-full text-left border-collapse">
|
|
<thead>
|
|
<tr
|
|
class="bg-gray-800/50 text-xs text-gray-400 uppercase tracking-wider border-b border-gray-700">
|
|
<th class="p-4 font-medium">Date</th>
|
|
<th class="p-4 font-medium text-right">Value</th>
|
|
<th class="p-4 font-medium text-right">Trend</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="metric-history-table-body" class="divide-y divide-gray-800 text-sm">
|
|
<!-- Rows injected via JS -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- History Data Button -->
|
|
<button id="history-data-btn"
|
|
class="w-full mt-4 bg-gray-800/50 hover:bg-gray-800 border border-gray-700 text-white py-3 rounded-xl transition-colors flex items-center justify-between px-5">
|
|
<span class="font-medium">History data</span>
|
|
<i class="fas fa-chevron-right text-gray-400"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Modal: Add Challenge -->
|
|
<div id="add-challenge-modal"
|
|
class="fixed inset-0 z-50 flex items-center justify-center invisible opacity-0 transition-all duration-300">
|
|
<div class="absolute inset-0 bg-black/60 backdrop-blur-sm" id="modal-backdrop"></div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-2xl shadow-2xl w-full max-w-3xl mx-4 transform scale-95 transition-all duration-300 relative z-10 overflow-hidden flex flex-col max-h-[90vh]">
|
|
<div
|
|
class="p-5 border-b border-gray-100 dark:border-gray-700 flex justify-between items-center bg-gray-50 dark:bg-gray-800/50 flex-shrink-0">
|
|
<h2 class="text-xl font-bold text-gray-900 dark:text-white">New Challenge</h2>
|
|
<button id="close-modal-btn"
|
|
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors">
|
|
<i class="fas fa-times text-lg"></i>
|
|
</button>
|
|
</div>
|
|
<div class="p-6 overflow-y-auto custom-scrollbar">
|
|
<form id="create-challenge-form" class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
<!-- Left Column: Details -->
|
|
<div class="space-y-5">
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2">Basic
|
|
Info</label>
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label
|
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5">Challenge
|
|
Name</label>
|
|
<input type="text" name="name" required placeholder="e.g. 100 Pushups"
|
|
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none transition-all shadow-sm">
|
|
</div>
|
|
|
|
<div>
|
|
<label
|
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5">Description</label>
|
|
<textarea name="description" placeholder="What's your motivation?" rows="3"
|
|
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none transition-all shadow-sm resize-none"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="border-gray-100 dark:border-gray-700">
|
|
|
|
<div>
|
|
<label class="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2">Goals
|
|
& Schedule</label>
|
|
<div class="grid grid-cols-2 gap-4 mb-4">
|
|
<div>
|
|
<label id="daily-target-label"
|
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5">Target</label>
|
|
<div class="flex rounded-lg shadow-sm">
|
|
<input type="number" name="daily_target" required min="1" value="10"
|
|
class="w-full px-4 py-2.5 rounded-l-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none transition-all">
|
|
<select name="unit_type"
|
|
class="bg-gray-50 dark:bg-gray-600 border border-l-0 border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 rounded-r-lg px-3 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500 font-medium">
|
|
<option value="reps">Reps</option>
|
|
<option value="minutes">Mins</option>
|
|
<option value="pages">Pages</option>
|
|
<option value="km">Km</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label
|
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5">Frequency</label>
|
|
<select name="period_type" id="period-type-select"
|
|
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none transition-all shadow-sm">
|
|
<option value="daily" selected>Daily</option>
|
|
<option value="weekly">Weekly</option>
|
|
<option value="monthly">Monthly</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Dynamic Frequency Options -->
|
|
<div id="frequency-sub-options"
|
|
class="bg-brand-50/50 dark:bg-brand-900/10 p-4 rounded-xl border border-brand-100 dark:border-brand-900/30 transition-all">
|
|
<!-- Daily -->
|
|
<div id="daily-options">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<span
|
|
class="block text-sm font-semibold text-gray-900 dark:text-gray-100">Rest
|
|
Days</span>
|
|
<span class="text-xs text-gray-500 dark:text-gray-400">Skip specific
|
|
days without breaking streaks</span>
|
|
</div>
|
|
<label class="relative inline-flex items-center cursor-pointer">
|
|
<input type="checkbox" id="rest-days-toggle" class="sr-only peer">
|
|
<div
|
|
class="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-brand-600">
|
|
</div>
|
|
</label>
|
|
</div>
|
|
<div id="rest-days-selector"
|
|
class="hidden grid-cols-4 gap-2 mt-3 pt-3 border-t border-brand-200/50 dark:border-brand-800/30">
|
|
<label
|
|
class="inline-flex items-center hover:bg-white dark:hover:bg-gray-800 p-1.5 rounded-lg transition-colors cursor-pointer select-none">
|
|
<input type="checkbox" name="rest_days" value="Saturday"
|
|
class="rounded text-brand-600 focus:ring-brand-500 border-gray-300 dark:border-gray-500">
|
|
<span
|
|
class="ml-2 text-sm text-gray-700 dark:text-gray-300">Saturday</span>
|
|
</label>
|
|
<label
|
|
class="inline-flex items-center hover:bg-white dark:hover:bg-gray-800 p-1.5 rounded-lg transition-colors cursor-pointer select-none">
|
|
<input type="checkbox" name="rest_days" value="Sunday"
|
|
class="rounded text-brand-600 focus:ring-brand-500 border-gray-300 dark:border-gray-500">
|
|
<span
|
|
class="ml-2 text-sm text-gray-700 dark:text-gray-300">Sunday</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Weekly -->
|
|
<div id="weekly-options" class="hidden">
|
|
<label class="block text-xs font-bold text-gray-500 uppercase mb-3">Select
|
|
Active Days</label>
|
|
<div class="flex flex-wrap gap-2">
|
|
<label class="cursor-pointer relative">
|
|
<input type="checkbox" name="weekly_days" value="Mon"
|
|
class="peer sr-only">
|
|
<span
|
|
class="inline-block px-3 py-1.5 rounded-full text-xs font-medium bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 peer-checked:bg-brand-600 peer-checked:text-white peer-checked:border-brand-600 transition-all">Mon</span>
|
|
</label>
|
|
<label class="cursor-pointer relative">
|
|
<input type="checkbox" name="weekly_days" value="Tue"
|
|
class="peer sr-only">
|
|
<span
|
|
class="inline-block px-3 py-1.5 rounded-full text-xs font-medium bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 peer-checked:bg-brand-600 peer-checked:text-white peer-checked:border-brand-600 transition-all">Tue</span>
|
|
</label>
|
|
<label class="cursor-pointer relative">
|
|
<input type="checkbox" name="weekly_days" value="Wed"
|
|
class="peer sr-only">
|
|
<span
|
|
class="inline-block px-3 py-1.5 rounded-full text-xs font-medium bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 peer-checked:bg-brand-600 peer-checked:text-white peer-checked:border-brand-600 transition-all">Wed</span>
|
|
</label>
|
|
<label class="cursor-pointer relative">
|
|
<input type="checkbox" name="weekly_days" value="Thu"
|
|
class="peer sr-only">
|
|
<span
|
|
class="inline-block px-3 py-1.5 rounded-full text-xs font-medium bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 peer-checked:bg-brand-600 peer-checked:text-white peer-checked:border-brand-600 transition-all">Thu</span>
|
|
</label>
|
|
<label class="cursor-pointer relative">
|
|
<input type="checkbox" name="weekly_days" value="Fri"
|
|
class="peer sr-only">
|
|
<span
|
|
class="inline-block px-3 py-1.5 rounded-full text-xs font-medium bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 peer-checked:bg-brand-600 peer-checked:text-white peer-checked:border-brand-600 transition-all">Fri</span>
|
|
</label>
|
|
<label class="cursor-pointer relative">
|
|
<input type="checkbox" name="weekly_days" value="Sat"
|
|
class="peer sr-only">
|
|
<span
|
|
class="inline-block px-3 py-1.5 rounded-full text-xs font-medium bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 peer-checked:bg-brand-600 peer-checked:text-white peer-checked:border-brand-600 transition-all">Sat</span>
|
|
</label>
|
|
<label class="cursor-pointer relative">
|
|
<input type="checkbox" name="weekly_days" value="Sun"
|
|
class="peer sr-only">
|
|
<span
|
|
class="inline-block px-3 py-1.5 rounded-full text-xs font-medium bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 peer-checked:bg-brand-600 peer-checked:text-white peer-checked:border-brand-600 transition-all">Sun</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Monthly -->
|
|
<div id="monthly-options" class="hidden">
|
|
<label class="block text-xs font-bold text-gray-500 uppercase mb-2">Completion
|
|
Goal</label>
|
|
<div class="flex items-center">
|
|
<input type="number" name="frequency_count" min="1" max="31"
|
|
placeholder="10"
|
|
class="w-24 px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 outline-none text-center font-bold">
|
|
<span
|
|
class="ml-3 text-sm text-gray-600 dark:text-gray-300 font-medium">times
|
|
per month</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-4 mt-4">
|
|
<div>
|
|
<label
|
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5">Start
|
|
Date</label>
|
|
<input type="date" name="start_date" required
|
|
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none transition-all shadow-sm">
|
|
</div>
|
|
<div>
|
|
<label
|
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5">End
|
|
Date <span
|
|
class="text-xs text-gray-400 font-normal">(Optional)</span></label>
|
|
<input type="date" name="end_date"
|
|
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none transition-all shadow-sm">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Column: Visuals -->
|
|
<div class="space-y-5 flex flex-col">
|
|
<label class="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2">Visual
|
|
Style</label>
|
|
|
|
<!-- Icon Selector -->
|
|
<div
|
|
class="bg-gray-50 dark:bg-gray-700/30 p-5 rounded-xl border border-gray-100 dark:border-gray-700">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">Choose an
|
|
Icon</label>
|
|
<div class="grid grid-cols-6 gap-2">
|
|
<!-- Row 1 -->
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-dumbbell" checked class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-dumbbell text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-person-running" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-person-running text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-person-swimming" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-person-swimming text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-bicycle" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-bicycle text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-person-hiking" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-person-hiking text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-fire" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-fire text-lg"></i>
|
|
</div>
|
|
</label>
|
|
|
|
<!-- Row 2 -->
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-heart-pulse" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-heart-pulse text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-stopwatch" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-stopwatch text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-book" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-book text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-glass-water" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-glass-water text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-bed" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-bed text-lg"></i>
|
|
</div>
|
|
</label>
|
|
<label class="cursor-pointer group">
|
|
<input type="radio" name="icon" value="fa-apple-whole" class="peer sr-only">
|
|
<div
|
|
class="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 flex items-center justify-center text-gray-400 peer-checked:bg-brand-500 peer-checked:text-white peer-checked:shadow-md border border-gray-200 dark:border-gray-600 peer-checked:border-brand-500 transition-all hover:border-brand-300">
|
|
<i class="fas fa-apple-whole text-lg"></i>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Image Selection -->
|
|
<div class="flex-grow flex flex-col min-h-0">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Visual
|
|
Reference <span class="text-xs text-gray-400 font-normal">(Optional)</span></label>
|
|
<input type="hidden" name="image_url" id="selected-image-url">
|
|
|
|
<div class="relative mb-3 group" id="custom-image-dropdown">
|
|
<button type="button" id="dropdown-button"
|
|
class="w-full px-4 py-2.5 text-left bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 flex items-center justify-between text-gray-900 dark:text-white transition-all hover:border-gray-400 dark:hover:border-gray-500">
|
|
<div class="flex items-center gap-2 overflow-hidden">
|
|
<i class="fas fa-image text-brand-500"></i>
|
|
<span id="dropdown-selected-text"
|
|
class="text-gray-600 dark:text-gray-300 text-sm truncate">Select
|
|
animation...</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down text-gray-400 text-xs transition-transform duration-200 group-hover:text-gray-600"
|
|
id="dropdown-arrow"></i>
|
|
</button>
|
|
|
|
<div id="dropdown-menu"
|
|
class="hidden absolute z-20 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-xl max-h-56 overflow-y-auto custom-scrollbar ring-1 ring-black ring-opacity-5">
|
|
<div id="dropdown-options" class="p-2 grid grid-cols-1 gap-1">
|
|
<!-- Options injected via JS -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Preview Box -->
|
|
<div id="image-preview-container"
|
|
class="hidden flex-grow relative rounded-xl border-2 border-dashed border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 flex items-center justify-center overflow-hidden min-h-[160px] group">
|
|
<img id="image-preview" src="" alt="Preview"
|
|
class="w-full h-full object-contain p-4 max-h-56 transition-transform duration-500 group-hover:scale-105">
|
|
</div>
|
|
<!-- Placeholder if no image selected -->
|
|
<div id="no-image-placeholder"
|
|
class="flex-grow relative rounded-xl border-2 border-dashed border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 flex flex-col items-center justify-center min-h-[160px] text-gray-400 transition-colors hover:bg-gray-100 dark:hover:bg-gray-800">
|
|
<div class="p-3 bg-white dark:bg-gray-700 rounded-full mb-3 shadow-sm text-brand-100">
|
|
<i class="fas fa-image text-2xl text-gray-300 dark:text-gray-600"></i>
|
|
</div>
|
|
<span class="text-xs font-medium text-gray-500 dark:text-gray-400">No visual
|
|
selected</span>
|
|
<span class="text-[10px] text-gray-400 mt-1">Select from dropdown above</span>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<div
|
|
class="md:col-span-2 pt-6 border-t border-gray-100 dark:border-gray-700 flex justify-end gap-3 items-center">
|
|
<button type="button" onclick="document.getElementById('close-modal-btn').click()"
|
|
class="px-5 py-2.5 rounded-lg text-sm font-medium text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors focus:outline-none focus:ring-2 focus:ring-gray-200 dark:focus:ring-gray-700">
|
|
Cancel
|
|
</button>
|
|
<button type="submit"
|
|
class="bg-brand-600 hover:bg-brand-500 text-white font-medium px-8 py-2.5 rounded-lg shadow-lg hover:shadow-xl shadow-brand-500/20 transition-all active:scale-95 text-sm flex items-center gap-2 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-500 dark:focus:ring-offset-gray-800">
|
|
<i class="fas fa-plus"></i> Create Challenge
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal: Stats -->
|
|
<div id="stats-modal"
|
|
class="fixed inset-0 z-50 flex items-center justify-center invisible opacity-0 transition-all duration-300">
|
|
<div class="absolute inset-0 bg-black/60 backdrop-blur-sm" id="stats-modal-backdrop"></div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-2xl shadow-2xl w-full max-w-4xl mx-4 transform scale-95 transition-all duration-300 relative z-10 overflow-hidden flex flex-col max-h-[90vh]">
|
|
<div
|
|
class="p-6 border-b border-gray-100 dark:border-gray-700 flex justify-between items-center bg-gray-50 dark:bg-gray-800/50">
|
|
<h2 class="text-xl font-bold text-gray-900 dark:text-white">Analytics</h2>
|
|
<button id="close-stats-modal-btn"
|
|
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors">
|
|
<i class="fas fa-times text-lg"></i>
|
|
</button>
|
|
</div>
|
|
<div class="p-6 overflow-y-auto">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div class="bg-gray-50 dark:bg-gray-700/50 p-4 rounded-xl">
|
|
<h3 class="text-sm font-semibold mb-4 text-gray-700 dark:text-gray-300">Total Reps (Last 7 Days)
|
|
</h3>
|
|
<canvas id="chart-reps"></canvas>
|
|
</div>
|
|
<div class="bg-gray-50 dark:bg-gray-700/50 p-4 rounded-xl">
|
|
<h3 class="text-sm font-semibold mb-4 text-gray-700 dark:text-gray-300">Completion Trends</h3>
|
|
<canvas id="chart-completion"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="mt-6 bg-gray-50 dark:bg-gray-700/50 p-4 rounded-xl">
|
|
<h3 class="text-sm font-semibold mb-4 text-gray-700 dark:text-gray-300">Consistency Heatmap (Last
|
|
365 Days)</h3>
|
|
<div id="consistency-heatmap" class="overflow-x-auto pb-2">
|
|
<!-- Heatmap injected here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Toast Container -->
|
|
<div id="toast-container" class="fixed bottom-5 right-5 z-50 flex flex-col gap-3 pointer-events-none">
|
|
<!-- Toasts go here -->
|
|
</div>
|
|
|
|
<!-- Date Picker Modal -->
|
|
<div id="date-picker-modal"
|
|
class="fixed inset-0 z-50 flex items-center justify-center invisible opacity-0 transition-all duration-300">
|
|
<div class="absolute inset-0 bg-black/60 backdrop-blur-sm" id="date-picker-backdrop"></div>
|
|
<div
|
|
class="bg-white dark:bg-gray-800 rounded-2xl shadow-2xl w-full max-w-md mx-4 transform scale-95 transition-all duration-300 relative z-10 overflow-hidden">
|
|
<!-- Header -->
|
|
<div
|
|
class="p-5 border-b border-gray-100 dark:border-gray-700 flex justify-between items-center bg-gradient-to-r from-brand-500 to-purple-600">
|
|
<h2 class="text-lg font-bold text-white flex items-center gap-2">
|
|
<i class="fas fa-calendar-alt"></i>
|
|
Select Date Period
|
|
</h2>
|
|
<button id="close-date-picker-btn" class="text-white/80 hover:text-white transition-colors">
|
|
<i class="fas fa-times text-lg"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="p-6 space-y-6">
|
|
<!-- Quick Presets -->
|
|
<div>
|
|
<h3 class="text-sm font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">Quick
|
|
Select</h3>
|
|
<div class="grid grid-cols-2 gap-2">
|
|
<button data-preset="today"
|
|
class="preset-btn px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 hover:border-brand-500 dark:hover:border-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-all text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-brand-600 dark:hover:text-brand-400 flex items-center justify-center gap-2">
|
|
<i class="fas fa-calendar-day text-xs"></i>
|
|
Today
|
|
</button>
|
|
<button data-preset="yesterday"
|
|
class="preset-btn px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 hover:border-brand-500 dark:hover:border-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-all text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-brand-600 dark:hover:text-brand-400 flex items-center justify-center gap-2">
|
|
<i class="fas fa-calendar-minus text-xs"></i>
|
|
Yesterday
|
|
</button>
|
|
<button data-preset="this-week"
|
|
class="preset-btn px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 hover:border-brand-500 dark:hover:border-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-all text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-brand-600 dark:hover:text-brand-400 flex items-center justify-center gap-2">
|
|
<i class="fas fa-calendar-week text-xs"></i>
|
|
This Week
|
|
</button>
|
|
<button data-preset="last-week"
|
|
class="preset-btn px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 hover:border-brand-500 dark:hover:border-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-all text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-brand-600 dark:hover:text-brand-400 flex items-center justify-center gap-2">
|
|
<i class="fas fa-calendar-week text-xs"></i>
|
|
Last Week
|
|
</button>
|
|
<button data-preset="this-month"
|
|
class="preset-btn px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 hover:border-brand-500 dark:hover:border-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-all text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-brand-600 dark:hover:text-brand-400 flex items-center justify-center gap-2">
|
|
<i class="fas fa-calendar text-xs"></i>
|
|
This Month
|
|
</button>
|
|
<button data-preset="last-30-days"
|
|
class="preset-btn px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 hover:border-brand-500 dark:hover:border-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-all text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-brand-600 dark:hover:text-brand-400 flex items-center justify-center gap-2">
|
|
<i class="fas fa-calendar-alt text-xs"></i>
|
|
Last 30 Days
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Divider -->
|
|
<div class="relative">
|
|
<div class="absolute inset-0 flex items-center">
|
|
<div class="w-full border-t border-gray-200 dark:border-gray-700"></div>
|
|
</div>
|
|
<div class="relative flex justify-center text-xs">
|
|
<span
|
|
class="px-2 bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 uppercase tracking-wider">Or</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Custom Date/Period Input -->
|
|
<div>
|
|
<h3 class="text-sm font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">Custom
|
|
Date or Period</h3>
|
|
|
|
<!-- Selection Type Toggle -->
|
|
<div class="flex gap-2 mb-4 bg-gray-100 dark:bg-gray-900 p-1 rounded-lg">
|
|
<button id="single-date-toggle"
|
|
class="date-type-toggle flex-1 px-3 py-2 rounded-md text-xs font-medium transition-all bg-white dark:bg-gray-700 shadow-sm text-brand-600 dark:text-brand-400">
|
|
<i class="fas fa-calendar-day mr-1"></i>
|
|
Single Day
|
|
</button>
|
|
<button id="date-range-toggle"
|
|
class="date-type-toggle flex-1 px-3 py-2 rounded-md text-xs font-medium transition-all text-gray-500 dark:text-gray-400">
|
|
<i class="fas fa-calendar-week mr-1"></i>
|
|
Date Range
|
|
</button>
|
|
</div>
|
|
|
|
<div class="space-y-3">
|
|
<!-- Single Date View -->
|
|
<div id="single-date-view">
|
|
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1.5">Select
|
|
Date</label>
|
|
<input type="date" id="custom-date-input"
|
|
class="w-full px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-white focus:border-brand-500 dark:focus:border-brand-400 focus:ring-2 focus:ring-brand-500/20 transition-all text-sm">
|
|
</div>
|
|
|
|
<!-- Date Range View -->
|
|
<div id="date-range-view" class="hidden space-y-3">
|
|
<div>
|
|
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1.5">Start
|
|
Date</label>
|
|
<input type="date" id="custom-start-date"
|
|
class="w-full px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-white focus:border-brand-500 dark:focus:border-brand-400 focus:ring-2 focus:ring-brand-500/20 transition-all text-sm">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1.5">End
|
|
Date</label>
|
|
<input type="date" id="custom-end-date"
|
|
class="w-full px-4 py-2.5 rounded-lg border-2 border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-white focus:border-brand-500 dark:focus:border-brand-400 focus:ring-2 focus:ring-brand-500/20 transition-all text-sm">
|
|
</div>
|
|
<!-- Period Info -->
|
|
<div id="period-info"
|
|
class="hidden p-3 bg-brand-50 dark:bg-brand-900/20 rounded-lg border border-brand-200 dark:border-brand-800">
|
|
<div class="flex items-center gap-2 text-xs">
|
|
<i class="fas fa-info-circle text-brand-600 dark:text-brand-400"></i>
|
|
<span class="text-brand-700 dark:text-brand-300 font-medium"
|
|
id="period-info-text"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button id="apply-custom-date-btn"
|
|
class="w-full bg-gradient-to-r from-brand-500 to-purple-600 hover:from-brand-600 hover:to-purple-700 text-white px-4 py-2.5 rounded-lg font-medium transition-all shadow-md hover:shadow-lg active:scale-95 flex items-center justify-center gap-2">
|
|
<i class="fas fa-check"></i>
|
|
<span id="apply-btn-text">Apply Custom Date</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Anime.js -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
|
|
<!-- Chart.js -->
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<!-- SortableJS -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.0/Sortable.min.js"></script>
|
|
<script src="app.js?v=17"></script>
|
|
</body>
|
|
|
|
</html> |