Skip to content

vermaabhii/FitLog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ‹οΈ FitLog – Gym Progress Tracker

A clean, beginner-friendly web app to log your workouts, track progress over time, and stay motivated β€” all without any backend or framework.

FitLog Banner HTML CSS JavaScript


πŸ“‹ Table of Contents


🌟 Overview

FitLog is a zero-dependency, client-side web application that helps gym-goers track their workout sessions. Log exercises with weights and reps, visualise progress over time, filter your history, and never lose your data β€” everything is stored locally in your browser using LocalStorage.

Built with only HTML, CSS, and Vanilla JavaScript β€” no React, no Node.js, no database, no internet connection required.


πŸš€ Live Demo

Since FitLog is a pure client-side app, you can run it directly by opening index.html in any modern browser. No server or build step needed.

πŸ“ FitLog-Gym Progress Tracker/
└── index.html  ← Just open this!

✨ Features

Core Features

Feature Description
Add Workout Log exercise name, weight (kg), reps, and date
Workout History View all logged entries sorted newest-first by default
Delete Entry Remove individual workout entries instantly
Filter by Exercise Live search to filter history by exercise name
Sort Options Sort by Newest, Oldest, Exercise Name, or Weight
Progress Indicator See weight change (β–² +5kg / β–Ό -5kg / = Same) vs. previous session
Quick Stats Total sessions, unique exercises, most logged, last workout date
Auto Date Date field pre-filled with today, but fully editable
LocalStorage All data persists across page reloads and browser restarts
Clear All Delete entire workout history with a confirmation modal
Toast Notifications Instant feedback on add, delete, and clear actions
Autocomplete Exercise name input suggests previously used exercises

UI / UX Extras

  • Dark gym theme with deep charcoal backgrounds and vibrant indigo/purple accents
  • Animated background blobs for a premium visual feel
  • Card-based layout with glassmorphism-inspired styling
  • Hover micro-animations on workout cards (slide + glow)
  • Fully responsive β€” all screen sizes from 360px β†’ 1600px+
  • Accessible β€” semantic HTML, ARIA labels, keyboard navigation
  • Print styles β€” prints cleanly without UI chrome
  • Reduced motion β€” respects prefers-reduced-motion OS setting
  • Touch-optimised β€” bigger tap targets on mobile devices

πŸ“ Project Structure

FitLog-Gym Progress Tracker/
β”‚
β”œβ”€β”€ index.html      # App shell β€” HTML structure and semantic markup
β”œβ”€β”€ style.css       # All styling β€” design tokens, components, responsive breakpoints
β”œβ”€β”€ script.js       # All logic β€” CRUD, LocalStorage, filtering, sorting, UI updates
└── README.md       # This file

The project deliberately avoids build tools, bundlers, or package managers so it stays beginner-friendly and universally openable.


🏁 Getting Started

Just Open It

  1. Download or clone this repository
  2. Navigate to the folder
  3. Double-click index.html β€” it opens in your default browser

No npm install, no npm run dev, no terminal required.


🧠 How It Works

Logic Flow

Page Load
    β”‚
    β–Ό
loadWorkouts() ← reads from LocalStorage
    β”‚
    β–Ό
render() ← builds the workout list + stats
    β”‚
    β”œβ”€β”€ No workouts? β†’ show empty state
    β”œβ”€β”€ Filter active? β†’ show filtered results
    └── Show workout cards with progress badges


Add Workout (form submit)
    β”‚
    β”œβ”€β”€ validateForm() β†’ show inline errors if invalid
    β”œβ”€β”€ Build workout object { id, exercise, weight, reps, date }
    β”œβ”€β”€ workouts.unshift(entry) β†’ add to top of array
    β”œβ”€β”€ saveWorkouts() β†’ JSON.stringify to LocalStorage
    └── render() + showToast()


Delete Workout (click trash icon)
    β”‚
    β”œβ”€β”€ Remove entry from array by ID
    β”œβ”€β”€ saveWorkouts() β†’ update LocalStorage
    └── render() + showToast()


Filter / Sort
    β”‚
    β”œβ”€β”€ filterInput event β†’ update filterQuery, re-render
    └── sortSelect change β†’ update sortMode, re-render


Clear All
    β”‚
    β”œβ”€β”€ Click "Clear All" β†’ open confirmation modal
    β”œβ”€β”€ Confirm β†’ workouts = [], saveWorkouts(), render()
    └── Cancel β†’ closeModal()

Progress Detection Logic

For each workout entry displayed, FitLog looks through the entire workout history for any previous entry with the same exercise name that has an earlier date. It picks the most recent one and compares weights:

delta = current.weight - previous.weight

delta > 0  β†’  β–² +{delta}kg  (green badge)
delta < 0  β†’  β–Ό {delta}kg   (red badge)
delta = 0  β†’  = Same        (grey badge)
no prior   β†’  (no badge)    (first entry)

πŸ’Ύ Data Storage

FitLog uses the browser's LocalStorage API to persist data. No data is ever sent to a server.

Storage Key

fitlog_workouts_v1

Data Schema

Each workout is stored as a JSON object in an array:

[
  {
    "id": "lf3k2abc9",
    "exercise": "Bench Press",
    "weight": 85,
    "reps": 10,
    "date": "2026-04-09"
  },
  {
    "id": "lf3k1xyz7",
    "exercise": "Squat",
    "weight": 100,
    "reps": 8,
    "date": "2026-04-08"
  }
]
Field Type Description
id string Unique ID generated from Date.now() + random suffix
exercise string Exercise name as entered by the user
weight number Weight in kilograms
reps number Number of repetitions
date string ISO date in YYYY-MM-DD format

Storage Helpers

// Read
JSON.parse(localStorage.getItem('fitlog_workouts_v1')) || []

// Write
localStorage.setItem('fitlog_workouts_v1', JSON.stringify(workouts))

⚠️ Note: LocalStorage is browser and device specific. Data does not sync across devices. If you clear browser data/site data, your workout history will be erased.


πŸ“± Responsive Design

FitLog is fully responsive across 9 breakpoints using a mobile-first approach:

Breakpoint Width Layout
Large Desktop β‰₯ 1280px Wide 2-col, more padding, larger cards
Desktop 1024px–1280px Standard 2-col, narrower sidebar
Tablet Landscape ≀ 1024px Sidebar shrinks to 300px
Tablet Portrait ≀ 900px Stacked single column, stats as 4-col row
Large Mobile ≀ 640px Full single column, full-width buttons
Small Mobile ≀ 480px Tighter padding, dot separators hidden
Extra Small ≀ 360px Minimal header, header stats hidden
Touch Devices hover:none Bigger tap targets (42px delete btn)
Reduced Motion OS setting All animations disabled

πŸ”§ Technical Details

XSS Prevention

All user-entered content is sanitised before being inserted into the DOM using an escapeHtml() utility:

function escapeHtml(str) {
  return String(str)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

This prevents Cross-Site Scripting (XSS) attacks from malicious exercise names.

Unique ID Generation

Each workout gets a unique ID that survives array mutation:

function generateId() {
  return Date.now().toString(36) + Math.random().toString(36).slice(2, 7);
}
// Example output: "lf3k2abc9"

Sorting

Sorting is non-destructive β€” the original workouts array is never mutated for display:

function sortWorkouts(arr) {
  const copy = [...arr]; // spread to avoid mutating source
  switch (sortMode) {
    case 'oldest':   return copy.sort((a, b) => new Date(a.date) - new Date(b.date));
    case 'exercise': return copy.sort((a, b) => a.exercise.localeCompare(b.exercise));
    case 'weight':   return copy.sort((a, b) => b.weight - a.weight);
    default:         return copy.sort((a, b) => new Date(b.date) - new Date(a.date));
  }
}

CSS Architecture

Styles follow a strict token-first architecture:

:root              β†’ Design tokens (colours, radii, shadows, transitions)
Reset & Base       β†’ Box-sizing, font, overflow
Background Blobs   β†’ Animated ambient gradients
Layout             β†’ App wrapper, header, main grid
Cards              β†’ Shared card + card-header + card-icon system
Form               β†’ Input grid, input wrappers, field errors
Buttons            β†’ btn base + modifiers (primary, danger, ghost)
Quick Stats        β†’ Stats grid and stat boxes
History            β†’ Header, filter controls, search wrapper
Workout List       β†’ Item cards, meta chips, progress badges
Empty States       β†’ Centred empty/no-results prompts
Modal              β†’ Backdrop + modal box
Toast              β†’ Slide-up notifications with dot indicators
Footer / Scrollbar β†’ Minor finishing styles
Responsive (x9)    β†’ Full multi-breakpoint overrides

CSS Custom Properties (Design Tokens)

--bg-deep       #0a0b10   /* Page background  */
--bg-card       #12141f   /* Card surfaces     */
--bg-input      #1c1e2e   /* Input backgrounds */
--accent        #6366f1   /* Indigo β€” primary  */
--purple        #a855f7   /* Purple β€” accents  */
--gold          #f59e0b   /* Gold β€” stats icon */
--green         #22c55e   /* Progress up       */
--red           #ef4444   /* Delete / progress down */
--text-primary  #f1f5f9
--text-muted    #64748b

⌨️ Keyboard & Accessibility

Key / Action Behaviour
Tab Navigate between all interactive elements
Enter on form Submits the Add Workout form
Escape Closes the Clear All confirmation modal
Form validation Inline errors shown below invalid fields
ARIA labels All icon-only buttons have aria-label
role="list" Workout history is semantically a list
aria-live="polite" Toast container announced to screen readers
role="dialog" + aria-modal Confirmation modal correctly identified
aria-labelledby All sections labelled by their headings

🌐 Browser Support

FitLog uses only stable, widely-supported Web APIs:

API Support
LocalStorage All modern browsers (Chrome, Firefox, Safari, Edge)
CSS Grid / Flexbox All modern browsers
CSS Custom Properties All modern browsers
datalist All modern browsers
backdrop-filter Chrome 76+, Firefox 103+, Safari 9+
prefers-reduced-motion All modern browsers

Internet Explorer is not supported (EOL since 2022).


πŸš€ Future Improvements

Here are features that could be added in future versions:

  • Charts & Graphs β€” Visualise weight progression per exercise using <canvas> or SVG
  • Export to CSV / JSON β€” Let users download their workout history
  • Import from JSON β€” Restore data from a backup file
  • Sets support β€” Log multiple sets per exercise in one entry
  • Rest timer β€” Built-in countdown timer between sets
  • Custom categories β€” Tag exercises (Push / Pull / Legs / Cardio)
  • Personal Records (PRs) β€” Highlight all-time best lifts with a πŸ† badge
  • Dark / Light mode toggle β€” Switch between themes
  • Weekly summary β€” "This week you did X sessions" dashboard
  • PWA support β€” Make it installable on mobile as a Progressive Web App
  • Body weight logging β€” Track body weight alongside workout data

🀝 Contributing

Contributions are welcome! Since this is a frontend-only project, contributions can be as simple as suggesting a UX improvement or fixing a CSS layout bug.

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/my-feature
  3. Commit your changes: git commit -m 'Add: my new feature'
  4. Push to the branch: git push origin feature/my-feature
  5. Open a Pull Request

Code Style Guidelines

  • Use 'use strict' in all JS
  • Keep functions small and single-purpose
  • Use JSDoc comments for all functions
  • Don't use innerHTML with unsanitised user input β€” always use escapeHtml()
  • CSS: follow the existing token-first architecture, no magic numbers

Built with πŸ’ͺ and Vanilla JS Β |Β  No frameworks. No backend. Just pure web.

⬆ Back to Top

About

A clean, dark-themed gym workout tracker web app. Log exercises, weights & reps. Track progress with before/after comparisons. Pure HTML, CSS & Vanilla JS. No frameworks, no backend.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors