Skip to content

Ranjini-ctrl/HerHealth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HerHealth – Daily Health & Wellness Hub

Live Website

view the Web --> https://herhelth.netlify.app/

A Women's Day special single-page wellness companion built with pure HTML5, CSS3, and vanilla JavaScript. No frameworks. No build tools. No backend. Just open index.html and go.


Table of Contents

  1. Overview
  2. Features
  3. Getting Started
  4. Project Structure
  5. Architecture
  6. Modules
  7. Data Persistence
  8. Design System
  9. Error Handling
  10. Testing
  11. Browser Compatibility

Overview

HerHealth is a unified daily wellness hub themed around Women's Day — "Healthy Women, Stronger World". It gives women a single place to track water intake, sleep, mood, menstrual cycles, reminders, nutrition, and exercise, all without requiring an account, a server, or an internet connection after the first load.

All user data is stored locally in the browser via localStorage. The app works offline and can be opened directly from the file system via a file:// URL.


Website Screenshots

image image image

Features

Feature Description
🌸 Women's Day Banner Animated hero banner with rotating inspirational quotes
💧 Water Tracker Log daily glasses consumed toward an 8-glass target
😴 Sleep Logger Record nightly sleep hours (0–24)
📅 Period Tracker Predict next period from last date + cycle length
⏰ Reminders Browser notifications for Water, Exercise, Medicine, Sleep
🥗 Nutrition Tips Daily meal suggestions that rotate by day of the week
🏃 Exercise & Yoga Beginner workout cards and yoga poses for stress relief
😊 Mood Tracker Log Happy / Sad / Stressed with contextual support messages
✨ Daily Motivation Random motivational quotes with a "New Quote" button
🎯 Health Score Live 0–100 score based on daily goal completions
🌙 Dark Mode Full light/dark theme toggle, persisted across sessions

Getting Started

No installation required.

# Clone or download the repository
git clone <repo-url>
cd herhealth-wellness-hub

# Open directly in your browser
open index.html          # macOS
start index.html         # Windows
xdg-open index.html      # Linux

That's it. The app runs entirely in the browser with no server needed.

Running the Tests

The test suite uses Vitest with jsdom.

# Install dev dependencies (one-time)
npm install

# Run all tests once
npm test
# or
npx vitest --run

Project Structure

herhealth-wellness-hub/
├── index.html                  # The entire application (HTML + CSS + JS)
├── package.json                # Dev dependencies (vitest, jsdom)
├── vitest.config.js            # Vitest configuration
└── tests/
    ├── helpers/
    │   └── loadPage.js         # jsdom helper — loads index.html into a test environment
    └── unit/
        ├── banner.test.js
        ├── dashboard.test.js
        ├── exercise.test.js
        ├── health-score.test.js
        ├── mood.test.js
        ├── motivation.test.js
        ├── nutrition.test.js
        ├── period-tracker.test.js
        ├── reminder.test.js
        └── theme.test.js

Everything lives in index.html. The CSS and JavaScript are embedded directly — no external files to serve.


Architecture

The app follows a modular IIFE (Immediately Invoked Function Expression) architecture. Each feature is a self-contained module that:

  • Owns its own DOM section
  • Manages its own localStorage keys
  • Registers its own event listeners
  • Exposes a minimal public API

A thin App controller bootstraps all modules in order on DOMContentLoaded.

App.init()
  ├── ThemeModule.init()
  ├── BannerModule.init()
  ├── HealthScoreModule.init()
  ├── DashboardModule.init()
  ├── PeriodTrackerModule.init()
  ├── ReminderModule.init()
  ├── NutritionModule.init()
  ├── ExerciseModule.init()
  ├── MoodModule.init()
  └── MotivationModule.init()

Data flow:

  1. On page load, App.init() calls each module's init().
  2. Each module reads its localStorage keys and hydrates the DOM.
  3. User interactions trigger module handlers → update DOM + localStorage.
  4. Modules that affect the health score call HealthScoreModule.recalculate().
  5. ReminderModule runs a setInterval at 60-second resolution to fire scheduled notifications.

Modules that feed into HealthScoreModule:

DashboardModule  ──(water, sleep)──┐
MoodModule       ──(mood)──────────┼──► HealthScoreModule.recalculate()
ReminderModule   ──(reminder)──────┘

Modules

ThemeModule

Manages the light/dark color theme.

Public API:

ThemeModule.init()       // Reads hh_theme from localStorage, applies theme before first paint
ThemeModule.toggle()     // Switches between 'light' and 'dark', persists preference
ThemeModule.getTheme()   // Returns 'light' | 'dark'

localStorage key: hh_theme

Example — reading the current theme:

const theme = ThemeModule.getTheme(); // 'light' or 'dark'

Behavior:

  • Defaults to 'light' when no preference is stored
  • Applies the dark CSS class to <body> for dark mode
  • Theme switch completes within 300ms via CSS transition
  • The toggle button (🌙 / ☀️) lives in the sticky nav bar

BannerModule

Renders the Women's Day hero banner with a random inspirational quote.

Public API:

BannerModule.init()   // Picks a random quote and renders it into #banner-quote

No persistent state.

Example quote rendered:

"She believed she could, so she did. — R.S. Grey"

The banner uses a CSS bannerFadeIn animation on load and displays the tagline "Healthy Women, Stronger World".


DashboardModule

The main daily metrics hub — tracks water intake and sleep hours, and provides shortcuts to mood and health score.

Public API:

DashboardModule.init()               // Restores state, checks date rollover
DashboardModule.incrementWater()     // +1 glass (no upper limit), persists, recalculates score
DashboardModule.decrementWater()     // -1 glass (floor: 0), persists, recalculates score
DashboardModule.saveSleep(hours)     // Validates 0–24, persists, recalculates score
DashboardModule.resetIfNewDay()      // Resets daily metrics if hh_last_date ≠ today

localStorage keys: hh_water, hh_sleep, hh_last_date

Example — saving sleep hours:

DashboardModule.saveSleep(7.5);  // Saves 7.5 hours, updates health score
DashboardModule.saveSleep(25);   // Invalid — shows error, does not save

Date rollover behavior:

When the page loads on a new calendar day, resetIfNewDay() automatically clears hh_water and hh_sleep back to their defaults so each day starts fresh.


PeriodTrackerModule

Predicts the next menstrual period based on the last period date and cycle length.

Public API:

PeriodTrackerModule.init()                          // Restores saved data, re-renders last prediction
PeriodTrackerModule.calculate(lastDate, cycleLength) // Validates inputs, computes next date, persists
PeriodTrackerModule.renderPrediction(date)           // Formats and displays the predicted date
PeriodTrackerModule.showError(message)               // Shows an inline validation error

localStorage key: hh_period{ lastDate: "YYYY-MM-DD", cycleLength: number }

Validation rules:

Input Valid Range Error shown when
Last period date Any valid date Empty or non-date string
Cycle length 20–45 days Outside this range

Example:

Last period date: 2025-07-01
Cycle length:     28 days
→ Predicted next: Wednesday, 30 July 2025

ReminderModule

Schedules browser notifications (or in-app fallback alerts) for four wellness categories.

Public API:

ReminderModule.init()                              // Restores configs, starts 60s polling interval
ReminderModule.enableReminder(category, time, sound) // Enables a reminder, requests notification permission
ReminderModule.disableReminder(category)           // Disables a reminder
ReminderModule.poll()                              // Checks current time against all enabled reminders
ReminderModule.requestPermission()                 // Wraps Notification.requestPermission()
ReminderModule.dispatch(category)                  // Fires notification or in-app banner

localStorage key: hh_reminders → array of ReminderConfig

Supported categories:

Category Emoji Default time
Water 💧 08:00
Exercise 🏃 08:00
Medicine 💊 08:00
Sleep 😴 08:00

Example config stored in localStorage:

[
  { "category": "water",    "time": "09:00", "enabled": true,  "sound": true  },
  { "category": "exercise", "time": "07:30", "enabled": true,  "sound": false },
  { "category": "medicine", "time": "08:00", "enabled": false, "sound": false },
  { "category": "sleep",    "time": "22:00", "enabled": true,  "sound": false }
]

Notification fallback: If the browser denies notification permission, an in-app banner appears at the scheduled time and auto-dismisses after 5 seconds.


NutritionModule

Displays daily healthy meal suggestions that rotate by day of the week.

Public API:

NutritionModule.init()        // Computes today's day index, renders suggestions
NutritionModule.getDayIndex() // Returns 0 (Sunday) – 6 (Saturday)

No persistent state — content is deterministic by date.

Each meal slot (Breakfast, Lunch, Dinner) has 7 suggestions — one per day of the week.

Example (Monday = index 1):

Meal Suggestion
🌅 Breakfast Greek Yogurt & Honey 🍯
☀️ Lunch Lentil Soup 🍲
🌙 Dinner Stir-Fried Tofu & Greens 🥦

ExerciseModule

Renders beginner home workout cards and yoga poses for stress relief.

Public API:

ExerciseModule.init()   // Renders all exercise and yoga cards from static data

No persistent state.

Content:

  • 5 exercise cards — Jumping Jacks, Bodyweight Squats, Push-Ups, Glute Bridges, High Knees
  • 4 yoga cards — Child's Pose, Cat-Cow Stretch, Legs-Up-the-Wall, Seated Forward Fold

Each card includes a title, instruction text, and an emoji visual. The layout uses a responsive CSS grid that collapses to a single column on screens below 768px.


MoodModule

Lets users log their current mood and receive a contextual supportive message.

Public API:

MoodModule.init()              // Restores last mood from localStorage, highlights selection
MoodModule.selectMood(mood)    // 'happy' | 'sad' | 'stressed' — persists, shows message, recalculates score
MoodModule.renderMessage(mood) // Displays the contextual message for the given mood

localStorage key: hh_mood{ mood: string, timestamp: string }

Mood messages:

Mood Message
😊 Happy "That's wonderful! Keep spreading your joy today. 🌟"
😢 Sad "It's okay to feel sad. Be gentle with yourself today. 💙"
😰 Stressed "Take a deep breath. You've got this! Try a quick yoga pose. 🧘"

MotivationModule

Displays a random motivational quote from a curated list of 12 women's wellness quotes.

Public API:

MotivationModule.init()      // Picks a random quote and renders it
MotivationModule.newQuote()  // Picks a DIFFERENT random quote and updates the display
MotivationModule.getQuotes() // Returns the full quotes array (used in tests)

No persistent state.

Example quote:

"Self-care is not selfish. You cannot pour from an empty cup."

newQuote() guarantees the new quote is always different from the currently displayed one by filtering it out before selecting.


HealthScoreModule

Computes and displays a live 0–100 wellness score based on four daily goal completions.

Public API:

HealthScoreModule.init()        // Reads all metric states, renders initial score and progress bar
HealthScoreModule.recalculate() // Recomputes score from current localStorage state, animates bar
HealthScoreModule.getScore()    // Returns the current score (0–100)

localStorage key: hh_score

Score formula:

score = (completedGoals / 4) × 100

Each goal contributes 25 points:

Goal Condition Points
💧 Water 8 or more glasses logged today +25
😴 Sleep Any sleep value saved today +25
😊 Mood A mood selected today +25
⏰ Reminder At least one reminder enabled +25

Example scores:

0 goals completed  →   0 / 100
2 goals completed  →  50 / 100
4 goals completed  → 100 / 100

The progress bar animates smoothly whenever any goal state changes.


Data Persistence

All data is stored in localStorage under hh_* namespaced keys. No data ever leaves the browser.

Key Type Description
hh_theme 'light' | 'dark' Current color theme
hh_water number Glasses of water logged today
hh_sleep number | null Sleep hours logged today
hh_last_date string (ISO date) Date of last dashboard activity
hh_period JSON object Last period date + cycle length
hh_reminders JSON array All reminder configurations
hh_mood JSON object Last selected mood + timestamp
hh_score number Cached health score

Corruption recovery: If any stored value fails JSON.parse(), the module silently resets that key to its default and continues. No data from other keys is affected.

Private browsing / storage blocked: If localStorage is unavailable, all modules operate in-memory for the session and a one-time warning banner is shown to the user.


Design System

The app uses a CSS custom property–based design system defined in :root.

Color Palette

/* Light mode */
--color-primary:      #e91e8c;   /* Hot pink — primary actions */
--color-secondary:    #9c27b0;   /* Purple — accents, secondary actions */
--color-accent:       #ff4081;   /* Bright pink — hover states */
--color-bg:           #fff0f6;   /* Soft pink background */
--color-surface:      #ffffff;   /* Card / panel background */
--color-text:         #2d1b2e;   /* Main text */
--color-text-muted:   #7b5e7b;   /* Secondary text */
/* Dark mode (applied via body.dark) */
--color-bg:           #1a0a1e;
--color-surface:      #2d1b2e;
--color-text:         #f8e8ff;
--color-text-muted:   #ce93d8;

Responsive Breakpoints

Breakpoint Layout
< 768px Single column (mobile-first default)
≥ 768px 2-column card grid
≥ 1024px 3-column card grid
≥ 1200px Wider section padding

CSS Transitions

All interactive elements use CSS transitions for smooth feedback:

--transition-fast:  150ms ease;   /* Button hover, input focus */
--transition-base:  250ms ease;   /* Card hover */
--transition-slow:  300ms ease;   /* Theme switch, background changes */

Error Handling

Scenario Behavior
Period cycle length outside 20–45 Inline error shown, prediction blocked
Period date empty or invalid Inline error shown, prediction blocked
Sleep value outside 0–24 Inline error shown, save blocked
Water count goes below 0 Clamped to 0 silently
Notification permission denied In-app banner fallback (auto-dismisses in 5s)
localStorage unavailable In-memory mode + one-time warning banner
Corrupted localStorage value Reset to default, clean value written back
New calendar day detected Daily metrics (water, sleep) reset automatically

Testing

The test suite uses Vitest as the test runner and jsdom to simulate the browser environment. All modules are IIFEs embedded in index.html, so tests load the full HTML file into jsdom and interact with the live DOM.

Running Tests

npm test              # Run all tests once (--run flag)
npx vitest --run      # Equivalent
npx vitest            # Watch mode (for development)

Test Helper

tests/helpers/loadPage.js provides a loadPage(localStorageData?) utility that:

  1. Reads index.html from disk
  2. Creates a fresh jsdom instance with runScripts: 'dangerously'
  3. Pre-seeds localStorage with any provided key/value pairs
  4. Fires DOMContentLoaded to trigger App.init()
  5. Returns { window, document } for assertions
import { loadPage } from '../helpers/loadPage.js';

// Load with no pre-existing data
const { document } = loadPage();

// Load with pre-seeded localStorage
const { document } = loadPage({ hh_theme: 'dark', hh_water: '5' });

Test Coverage

File Module tested Tests
theme.test.js ThemeModule 4
banner.test.js BannerModule 2
health-score.test.js HealthScoreModule 3
dashboard.test.js DashboardModule 5
period-tracker.test.js PeriodTrackerModule 9
reminder.test.js ReminderModule 4
nutrition.test.js NutritionModule 5
exercise.test.js ExerciseModule 6
mood.test.js MoodModule 4
motivation.test.js MotivationModule 6
Total 48

Example Test

// tests/unit/dashboard.test.js
it('date rollover: set hh_last_date to yesterday, init, verify water resets to 0', () => {
  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);
  const yesterdayStr = yesterday.toISOString().slice(0, 10);

  const { document } = loadPage({
    hh_last_date: yesterdayStr,
    hh_water: '5',
  });

  const waterEl = document.getElementById('water-count');
  expect(waterEl.textContent.trim()).toBe('0');
});

Browser Compatibility

The app uses standard Web APIs available in all modern browsers:

API Used for
localStorage All data persistence
Notification Reminder browser notifications
setInterval Reminder polling (60s resolution)
CSS Custom Properties Design system / theming
CSS Grid Responsive card layouts
Date.toLocaleDateString Period date formatting

Minimum recommended browsers: Chrome 80+, Firefox 75+, Safari 13+, Edge 80+

The app degrades gracefully when Notification permission is denied (in-app fallback) and when localStorage is unavailable (in-memory mode).

About

HerHealth - It is a simple wellness website designed for women to track daily health activities like water intake, sleep, mood, and fitness. Built using HTML, CSS, and JavaScript, it offers a private, easy-to-use experience without any login or backend.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors