myworkouts / index.html
jrrade's picture
Add 2 files
ffd507a verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Workout Logger - Push Legs Pull Split</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.fade-in {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.workout-day.active {
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
}
.progress-bar {
transition: width 0.5s ease-in-out;
}
.history-item {
transition: all 0.2s ease;
cursor: pointer;
}
.history-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.history-item.active {
border-left: 4px solid #3b82f6;
}
.history-exercises {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.history-exercises.show {
max-height: 1000px;
}
.edit-history-form {
background-color: rgba(243, 244, 246, 0.8);
backdrop-filter: blur(5px);
}
</style>
</head>
<body class="bg-gray-100 min-h-screen">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<!-- Header -->
<header class="mb-8 text-center">
<h1 class="text-4xl font-bold text-blue-600 mb-2">Workout Logger</h1>
<p class="text-gray-600">Track your Push, Legs, Pull split progress</p>
</header>
<!-- Week Navigation -->
<div class="bg-white rounded-xl shadow-md p-4 mb-6">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold text-gray-800">This Week</h2>
<div class="flex space-x-2">
<button id="prev-week" class="p-2 rounded-full bg-gray-200 hover:bg-gray-300">
<i class="fas fa-chevron-left"></i>
</button>
<button id="next-week" class="p-2 rounded-full bg-gray-200 hover:bg-gray-300">
<i class="fas fa-chevron-right"></i>
</button>
</div>
</div>
<div class="grid grid-cols-6 gap-2">
<div class="workout-day rounded-lg p-3 text-center cursor-pointer transition-all" data-day="monday" data-type="push">
<div class="font-medium">Monday</div>
<div class="text-xs text-blue-500">Push</div>
</div>
<div class="workout-day rounded-lg p-3 text-center cursor-pointer transition-all" data-day="tuesday" data-type="pull">
<div class="font-medium">Tuesday</div>
<div class="text-xs text-green-500">Pull</div>
</div>
<div class="workout-day rounded-lg p-3 text-center cursor-pointer transition-all" data-day="wednesday" data-type="legs">
<div class="font-medium">Wednesday</div>
<div class="text-xs text-purple-500">Legs</div>
</div>
<div class="workout-day rounded-lg p-3 text-center cursor-pointer transition-all" data-day="thursday" data-type="push">
<div class="font-medium">Thursday</div>
<div class="text-xs text-blue-500">Push</div>
</div>
<div class="workout-day rounded-lg p-3 text-center cursor-pointer transition-all" data-day="friday" data-type="pull">
<div class="font-medium">Friday</div>
<div class="text-xs text-green-500">Pull</div>
</div>
<div class="workout-day rounded-lg p-3 text-center cursor-pointer transition-all" data-day="saturday" data-type="legs">
<div class="font-medium">Saturday</div>
<div class="text-xs text-purple-500">Legs</div>
</div>
</div>
</div>
<!-- Current Workout -->
<div id="current-workout" class="bg-white rounded-xl shadow-md p-6 mb-6 fade-in">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold text-gray-800">
<span id="current-day">Monday</span> -
<span id="workout-type" class="text-blue-500">Push</span>
</h2>
<div class="text-sm text-gray-500" id="workout-date">June 12, 2023</div>
</div>
<!-- Progress -->
<div class="mb-6">
<div class="flex justify-between text-sm mb-1">
<span>Workout Progress</span>
<span id="progress-percent">0%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div id="progress-bar" class="progress-bar h-2.5 rounded-full bg-blue-500" style="width: 0%"></div>
</div>
</div>
<!-- Exercises List -->
<div id="exercises-container" class="mb-6">
<!-- Exercises will be added here -->
</div>
<!-- Add Exercise Form -->
<div class="bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium mb-3">Add New Exercise</h3>
<div class="grid grid-cols-1 md:grid-cols-4 gap-3">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Exercise</label>
<input type="text" id="exercise-name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Bench Press">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Weight (lbs)</label>
<input type="number" id="exercise-weight" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="45">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Sets</label>
<input type="number" id="exercise-sets" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="3" value="3">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Reps</label>
<input type="number" id="exercise-reps" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="10" value="10">
</div>
</div>
<button id="add-exercise" class="mt-4 w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-md transition-colors">
<i class="fas fa-plus mr-2"></i> Add Exercise
</button>
</div>
</div>
<!-- Workout History -->
<div class="bg-white rounded-xl shadow-md p-6">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold text-gray-800">Workout History</h2>
<button id="toggle-history-view" class="text-sm text-blue-600 hover:text-blue-800">
<i class="fas fa-list mr-1"></i> Toggle View
</button>
</div>
<div id="history-container">
<!-- History items will be added here -->
<div class="text-center py-8 text-gray-400">
<i class="fas fa-dumbbell text-4xl mb-2"></i>
<p>Your workout history will appear here</p>
</div>
</div>
</div>
</div>
<!-- Edit History Modal -->
<div id="edit-history-modal" class="fixed inset-0 z-50 flex items-center justify-center hidden">
<div class="absolute inset-0 bg-black bg-opacity-50"></div>
<div class="edit-history-form relative bg-white rounded-xl shadow-xl p-6 w-full max-w-2xl max-h-[90vh] overflow-y-auto">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold">Edit Workout</h3>
<button id="close-edit-modal" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div id="edit-history-content">
<!-- Content will be added here -->
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const workoutDays = document.querySelectorAll('.workout-day');
const currentDayElement = document.getElementById('current-day');
const workoutTypeElement = document.getElementById('workout-type');
const workoutDateElement = document.getElementById('workout-date');
const exercisesContainer = document.getElementById('exercises-container');
const historyContainer = document.getElementById('history-container');
const progressBar = document.getElementById('progress-bar');
const progressPercent = document.getElementById('progress-percent');
const toggleHistoryViewBtn = document.getElementById('toggle-history-view');
const editHistoryModal = document.getElementById('edit-history-modal');
const editHistoryContent = document.getElementById('edit-history-content');
const closeEditModalBtn = document.getElementById('close-edit-modal');
// Form elements
const exerciseNameInput = document.getElementById('exercise-name');
const exerciseWeightInput = document.getElementById('exercise-weight');
const exerciseSetsInput = document.getElementById('exercise-sets');
const exerciseRepsInput = document.getElementById('exercise-reps');
const addExerciseBtn = document.getElementById('add-exercise');
// Data
let currentDay = 'monday';
let currentWorkoutType = 'push';
let workouts = {
monday: { exercises: [], completed: false, date: new Date().toISOString() },
tuesday: { exercises: [], completed: false, date: new Date().toISOString() },
wednesday: { exercises: [], completed: false, date: new Date().toISOString() },
thursday: { exercises: [], completed: false, date: new Date().toISOString() },
friday: { exercises: [], completed: false, date: new Date().toISOString() },
saturday: { exercises: [], completed: false, date: new Date().toISOString() }
};
// View state
let historyViewMode = 'detailed'; // 'detailed' or 'compact'
// Initialize the app
initApp();
// Event Listeners
workoutDays.forEach(day => {
day.addEventListener('click', function() {
currentDay = this.dataset.day;
currentWorkoutType = this.dataset.type;
updateUI();
});
});
addExerciseBtn.addEventListener('click', addExercise);
toggleHistoryViewBtn.addEventListener('click', toggleHistoryView);
closeEditModalBtn.addEventListener('click', () => editHistoryModal.classList.add('hidden'));
// Functions
function initApp() {
// Load data from localStorage if available
const savedWorkouts = localStorage.getItem('workoutLoggerData');
if (savedWorkouts) {
workouts = JSON.parse(savedWorkouts);
// Ensure all dates are properly formatted
Object.keys(workouts).forEach(day => {
if (workouts[day].date) {
// If date is already in ISO format, keep it
if (typeof workouts[day].date === 'string' && workouts[day].date.includes('T')) {
return;
}
// Otherwise, convert to ISO format
workouts[day].date = new Date(workouts[day].date).toISOString();
} else {
workouts[day].date = new Date().toISOString();
}
// Ensure each exercise has a date
workouts[day].exercises.forEach(exercise => {
if (!exercise.date) {
exercise.date = workouts[day].date;
} else if (!exercise.date.includes('T')) {
exercise.date = new Date(exercise.date).toISOString();
}
});
});
}
// Set current date
updateDate();
// Initialize UI
updateUI();
loadHistory();
}
function updateDate() {
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
const today = new Date();
workoutDateElement.textContent = today.toLocaleDateString('en-US', options);
}
function updateUI() {
// Update active day
workoutDays.forEach(day => {
day.classList.remove('active', 'bg-blue-50', 'bg-green-50', 'bg-purple-50');
if (day.dataset.day === currentDay) {
day.classList.add('active');
if (day.dataset.type === 'push') day.classList.add('bg-blue-50');
if (day.dataset.type === 'pull') day.classList.add('bg-green-50');
if (day.dataset.type === 'legs') day.classList.add('bg-purple-50');
}
});
// Update header
currentDayElement.textContent = currentDay.charAt(0).toUpperCase() + currentDay.slice(1);
workoutTypeElement.textContent = currentWorkoutType.charAt(0).toUpperCase() + currentWorkoutType.slice(1);
// Update color based on workout type
workoutTypeElement.className = '';
if (currentWorkoutType === 'push') workoutTypeElement.classList.add('text-blue-500');
if (currentWorkoutType === 'pull') workoutTypeElement.classList.add('text-green-500');
if (currentWorkoutType === 'legs') workoutTypeElement.classList.add('text-purple-500');
// Update exercises list
renderExercises();
// Update progress
updateProgress();
}
function renderExercises() {
exercisesContainer.innerHTML = '';
const dayExercises = workouts[currentDay].exercises;
if (dayExercises.length === 0) {
exercisesContainer.innerHTML = `
<div class="text-center py-8 text-gray-400">
<i class="fas fa-plus-circle text-4xl mb-2"></i>
<p>Add your first exercise to get started</p>
</div>
`;
return;
}
dayExercises.forEach((exercise, index) => {
const exerciseElement = document.createElement('div');
exerciseElement.className = 'exercise-item bg-gray-50 rounded-lg p-4 mb-3 fade-in';
exerciseElement.innerHTML = `
<div class="flex justify-between items-start mb-2">
<h3 class="font-medium">${exercise.name}</h3>
<div class="flex space-x-2">
<button class="edit-exercise p-1 text-blue-500 hover:text-blue-700" data-index="${index}">
<i class="fas fa-edit"></i>
</button>
<button class="delete-exercise p-1 text-red-500 hover:text-red-700" data-index="${index}">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<div class="grid grid-cols-3 gap-2 text-sm">
<div class="bg-white p-2 rounded">
<div class="text-gray-500">Weight</div>
<div>${exercise.weight} lbs</div>
</div>
<div class="bg-white p-2 rounded">
<div class="text-gray-500">Sets</div>
<div>${exercise.sets}</div>
</div>
<div class="bg-white p-2 rounded">
<div class="text-gray-500">Reps</div>
<div>${exercise.reps}</div>
</div>
</div>
<div class="text-xs text-gray-400 mt-1">${formatShortDate(exercise.date)}</div>
`;
exercisesContainer.appendChild(exerciseElement);
});
// Add event listeners to delete buttons
document.querySelectorAll('.delete-exercise').forEach(btn => {
btn.addEventListener('click', function() {
const index = parseInt(this.dataset.index);
deleteExercise(index);
});
});
// Add event listeners to edit buttons
document.querySelectorAll('.edit-exercise').forEach(btn => {
btn.addEventListener('click', function() {
const index = parseInt(this.dataset.index);
editExercise(index);
});
});
}
function addExercise() {
const name = exerciseNameInput.value.trim();
const weight = parseFloat(exerciseWeightInput.value);
const sets = parseInt(exerciseSetsInput.value);
const reps = parseInt(exerciseRepsInput.value);
if (!name || isNaN(weight) || isNaN(sets) || isNaN(reps)) {
alert('Please fill in all fields with valid values');
return;
}
const newExercise = {
name,
weight,
sets,
reps,
date: new Date().toISOString()
};
workouts[currentDay].exercises.push(newExercise);
workouts[currentDay].completed = workouts[currentDay].exercises.length > 0;
workouts[currentDay].date = new Date().toISOString();
saveData();
updateUI();
loadHistory();
// Reset form
exerciseNameInput.value = '';
exerciseWeightInput.value = '';
exerciseSetsInput.value = '3';
exerciseRepsInput.value = '10';
exerciseNameInput.focus();
}
function deleteExercise(index) {
if (confirm('Are you sure you want to delete this exercise?')) {
workouts[currentDay].exercises.splice(index, 1);
workouts[currentDay].completed = workouts[currentDay].exercises.length > 0;
saveData();
updateUI();
loadHistory();
}
}
function editExercise(index) {
const exercise = workouts[currentDay].exercises[index];
// Fill the form with exercise data
exerciseNameInput.value = exercise.name;
exerciseWeightInput.value = exercise.weight;
exerciseSetsInput.value = exercise.sets;
exerciseRepsInput.value = exercise.reps;
// Delete the exercise (we'll add it again when saved)
workouts[currentDay].exercises.splice(index, 1);
updateUI();
loadHistory();
// Focus on the name field
exerciseNameInput.focus();
}
function updateProgress() {
const dayExercises = workouts[currentDay].exercises;
const totalExercises = dayExercises.length;
// Simple progress calculation (could be enhanced)
const progress = totalExercises > 0 ? Math.min(100, totalExercises * 20) : 0;
progressBar.style.width = `${progress}%`;
progressPercent.textContent = `${progress}%`;
// Change color based on progress
progressBar.className = 'progress-bar h-2.5 rounded-full';
if (progress < 30) progressBar.classList.add('bg-red-500');
else if (progress < 70) progressBar.classList.add('bg-yellow-500');
else progressBar.classList.add('bg-green-500');
}
function saveData() {
localStorage.setItem('workoutLoggerData', JSON.stringify(workouts));
}
function loadHistory() {
historyContainer.innerHTML = '';
// Get all workout days that have exercises
const workoutDaysWithData = Object.entries(workouts)
.filter(([day, data]) => data.exercises.length > 0)
.sort((a, b) => new Date(b[1].date) - new Date(a[1].date));
if (workoutDaysWithData.length === 0) {
historyContainer.innerHTML = `
<div class="text-center py-8 text-gray-400">
<i class="fas fa-dumbbell text-4xl mb-2"></i>
<p>Your workout history will appear here</p>
</div>
`;
return;
}
workoutDaysWithData.forEach(([day, workoutData]) => {
const historyItem = document.createElement('div');
historyItem.className = 'history-item bg-gray-50 rounded-lg p-4 mb-3';
if (historyViewMode === 'detailed') {
historyItem.innerHTML = `
<div class="flex justify-between items-center mb-2">
<div>
<h3 class="font-medium">${day.charAt(0).toUpperCase() + day.slice(1)} -
<span class="${getWorkoutTypeColorClass(day)}">
${getWorkoutType(day)}
</span></h3>
<div class="text-xs text-gray-500">${formatDate(workoutData.date)}</div>
</div>
<div class="flex space-x-2">
<button class="edit-history p-1 text-blue-500 hover:text-blue-700" data-day="${day}">
<i class="fas fa-edit"></i>
</button>
<span class="text-sm text-gray-500">${workoutData.exercises.length} ex.</span>
</div>
</div>
<div class="flex space-x-2 text-sm mb-2">
<span class="bg-blue-100 text-blue-800 px-2 py-1 rounded">${workoutData.completed ? 'Completed' : 'In Progress'}</span>
<span class="bg-green-100 text-green-800 px-2 py-1 rounded">${formatShortDate(workoutData.date)}</span>
</div>
<div class="history-exercises">
${renderHistoryExercises(workoutData.exercises)}
</div>
`;
} else {
historyItem.innerHTML = `
<div class="flex justify-between items-center">
<div>
<h3 class="font-medium">${day.charAt(0).toUpperCase() + day.slice(1)} -
<span class="${getWorkoutTypeColorClass(day)}">
${getWorkoutType(day)}
</span></h3>
<div class="text-xs text-gray-500">${formatDate(workoutData.date)}</div>
</div>
<div class="flex space-x-2 items-center">
<button class="edit-history p-1 text-blue-500 hover:text-blue-700" data-day="${day}">
<i class="fas fa-edit"></i>
</button>
<span class="text-sm bg-blue-100 text-blue-800 px-2 py-1 rounded">${workoutData.exercises.length} ex.</span>
</div>
</div>
`;
}
historyContainer.appendChild(historyItem);
// Add click event to toggle exercises visibility (detailed view only)
if (historyViewMode === 'detailed') {
const header = historyItem.querySelector('.flex.justify-between.items-center');
const exercisesSection = historyItem.querySelector('.history-exercises');
header.addEventListener('click', function(e) {
// Don't toggle if clicking the edit button
if (!e.target.closest('.edit-history')) {
historyItem.classList.toggle('active');
exercisesSection.classList.toggle('show');
}
});
}
// Add event listener to edit button
historyItem.querySelector('.edit-history').addEventListener('click', function() {
const day = this.dataset.day;
openEditHistoryModal(day);
});
});
}
function renderHistoryExercises(exercises) {
if (exercises.length === 0) return '';
let html = '<div class="space-y-2">';
exercises.forEach((exercise, index) => {
html += `
<div class="bg-white p-3 rounded-lg border border-gray-200">
<div class="flex justify-between items-start">
<div class="font-medium">${exercise.name}</div>
<div class="flex space-x-2">
<button class="edit-history-exercise p-1 text-blue-500 hover:text-blue-700" data-index="${index}">
<i class="fas fa-edit"></i>
</button>
<button class="delete-history-exercise p-1 text-red-500 hover:text-red-700" data-index="${index}">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<div class="grid grid-cols-3 gap-2 text-sm mt-2">
<div>
<div class="text-gray-500">Weight</div>
<div>${exercise.weight} lbs</div>
</div>
<div>
<div class="text-gray-500">Sets</div>
<div>${exercise.sets}</div>
</div>
<div>
<div class="text-gray-500">Reps</div>
<div>${exercise.reps}</div>
</div>
</div>
<div class="text-xs text-gray-400 mt-1">${formatShortDate(exercise.date)}</div>
</div>
`;
});
html += '</div>';
return html;
}
function openEditHistoryModal(day) {
const workoutData = workouts[day];
editHistoryContent.innerHTML = `
<div class="mb-4">
<h4 class="font-medium text-lg mb-2">${day.charAt(0).toUpperCase() + day.slice(1)} Workout</h4>
<div class="text-sm text-gray-600 mb-4">${formatDate(workoutData.date)}</div>
<div class="flex items-center mb-4">
<label class="block text-sm font-medium text-gray-700 mr-2">Completed:</label>
<input type="checkbox" id="edit-completed" ${workoutData.completed ? 'checked' : ''} class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
</div>
<div class="mb-2">
<label class="block text-sm font-medium text-gray-700 mb-1">Workout Date</label>
<input type="datetime-local" id="edit-workout-date" value="${formatDateTimeLocal(workoutData.date)}" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
</div>
<div class="border-t border-gray-200 pt-4">
<h5 class="font-medium mb-3">Exercises</h5>
<div id="edit-exercises-list" class="space-y-3 mb-4">
${renderEditExercisesList(workoutData.exercises)}
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<h6 class="font-medium mb-2">Add New Exercise</h6>
<div class="grid grid-cols-1 md:grid-cols-4 gap-2">
<div>
<input type="text" id="new-exercise-name" placeholder="Exercise" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
<div>
<input type="number" id="new-exercise-weight" placeholder="Weight" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
<div>
<input type="number" id="new-exercise-sets" placeholder="Sets" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
<div>
<input type="number" id="new-exercise-reps" placeholder="Reps" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
</div>
<button id="add-new-exercise" class="mt-2 w-full bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded-md text-sm transition-colors">
<i class="fas fa-plus mr-1"></i> Add Exercise
</button>
</div>
</div>
<div class="flex justify-end space-x-3 mt-6">
<button id="cancel-edit" class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50">
Cancel
</button>
<button id="save-edit" data-day="${day}" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md text-sm font-medium">
Save Changes
</button>
</div>
`;
// Add event listeners to delete buttons
editHistoryContent.querySelectorAll('.delete-history-exercise').forEach(btn => {
btn.addEventListener('click', function() {
const index = parseInt(this.dataset.index);
if (confirm('Are you sure you want to delete this exercise?')) {
workoutData.exercises.splice(index, 1);
openEditHistoryModal(day); // Refresh the modal
}
});
});
// Add event listener to add new exercise button
editHistoryContent.querySelector('#add-new-exercise').addEventListener('click', function() {
const name = editHistoryContent.querySelector('#new-exercise-name').value.trim();
const weight = parseFloat(editHistoryContent.querySelector('#new-exercise-weight').value);
const sets = parseInt(editHistoryContent.querySelector('#new-exercise-sets').value);
const reps = parseInt(editHistoryContent.querySelector('#new-exercise-reps').value);
if (!name || isNaN(weight) || isNaN(sets) || isNaN(reps)) {
alert('Please fill in all fields with valid values');
return;
}
workoutData.exercises.push({
name,
weight,
sets,
reps,
date: new Date().toISOString()
});
openEditHistoryModal(day); // Refresh the modal
});
// Add event listener to save button
editHistoryContent.querySelector('#save-edit').addEventListener('click', function() {
const day = this.dataset.day;
const completed = editHistoryContent.querySelector('#edit-completed').checked;
const date = new Date(editHistoryContent.querySelector('#edit-workout-date').value).toISOString();
workouts[day].completed = completed;
workouts[day].date = date;
// Update all exercises dates if workout date changed
if (workouts[day].date !== workoutData.date) {
workouts[day].exercises.forEach(exercise => {
exercise.date = workouts[day].date;
});
}
saveData();
updateUI();
loadHistory();
editHistoryModal.classList.add('hidden');
});
// Add event listener to cancel button
editHistoryContent.querySelector('#cancel-edit').addEventListener('click', function() {
editHistoryModal.classList.add('hidden');
});
editHistoryModal.classList.remove('hidden');
}
function renderEditExercisesList(exercises) {
if (exercises.length === 0) return '<div class="text-center py-4 text-gray-400">No exercises</div>';
let html = '';
exercises.forEach((exercise, index) => {
html += `
<div class="bg-white p-3 rounded-lg border border-gray-200">
<div class="grid grid-cols-1 md:grid-cols-5 gap-2">
<div>
<label class="text-xs text-gray-500">Exercise</label>
<input type="text" value="${exercise.name}" data-index="${index}" data-field="name" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
<div>
<label class="text-xs text-gray-500">Weight</label>
<input type="number" value="${exercise.weight}" data-index="${index}" data-field="weight" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
<div>
<label class="text-xs text-gray-500">Sets</label>
<input type="number" value="${exercise.sets}" data-index="${index}" data-field="sets" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
<div>
<label class="text-xs text-gray-500">Reps</label>
<input type="number" value="${exercise.reps}" data-index="${index}" data-field="reps" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
<div>
<label class="text-xs text-gray-500">Actions</label>
<button class="delete-history-exercise w-full px-2 py-1 bg-red-500 hover:bg-red-600 text-white rounded-md text-sm" data-index="${index}">
<i class="fas fa-trash mr-1"></i> Delete
</button>
</div>
</div>
<div class="mt-2">
<label class="text-xs text-gray-500">Date</label>
<input type="datetime-local" value="${formatDateTimeLocal(exercise.date)}" data-index="${index}" data-field="date" class="w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
</div>
</div>
`;
});
// Add input change listeners
setTimeout(() => {
editHistoryContent.querySelectorAll('input[data-index]').forEach(input => {
input.addEventListener('change', function() {
const index = parseInt(this.dataset.index);
const field = this.dataset.field;
const value = field === 'name' ? this.value :
field === 'date' ? new Date(this.value).toISOString() :
parseFloat(this.value);
workouts[currentDay].exercises[index][field] = value;
});
});
}, 0);
return html;
}
function toggleHistoryView() {
historyViewMode = historyViewMode === 'detailed' ? 'compact' : 'detailed';
toggleHistoryViewBtn.innerHTML = historyViewMode === 'detailed' ?
'<i class="fas fa-list mr-1"></i> Compact View' :
'<i class="fas fa-list mr-1"></i> Detailed View';
loadHistory();
}
function getWorkoutType(day) {
if (day === 'monday' || day === 'thursday') return 'Push';
if (day === 'tuesday' || day === 'friday') return 'Pull';
if (day === 'wednesday' || day === 'saturday') return 'Legs';
return '';
}
function getWorkoutTypeColorClass(day) {
if (day === 'monday' || day === 'thursday') return 'text-blue-500';
if (day === 'tuesday' || day === 'friday') return 'text-green-500';
if (day === 'wednesday' || day === 'saturday') return 'text-purple-500';
return '';
}
function formatDate(dateString) {
try {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return 'Date not available';
}
return date.toLocaleDateString('en-US', {
weekday: 'long',
month: 'short',
day: 'numeric',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
console.error('Error formatting date:', e);
return 'Date not available';
}
}
function formatShortDate(dateString) {
try {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return '';
}
return date.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
console.error('Error formatting short date:', e);
return '';
}
}
function formatDateTimeLocal(dateString) {
try {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return '';
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day}T${hours}:${minutes}`;
} catch (e) {
console.error('Error formatting datetime-local:', e);
return '';
}
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=jrrade/myworkouts" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
</html>