Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/chrisdzasc/Time-Tracking-Dashboard/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Time Tracking Dashboard uses the Fetch API to load activity data from a JSON file, then dynamically updates the DOM with the retrieved values. This approach separates data from presentation and allows for easy updates without modifying HTML.

Fetch API Implementation

Data is loaded on page load using the Fetch API (app.js:1-11):
let dashboardData = [];

fetch('./js/data.json')
    .then(response => { 
        return response.json()
    })
    .then(data => {
        dashboardData = data;
        
        weeklyActivity();
    });

Fetch Flow

  1. Initialize empty array: dashboardData is declared as an empty array
  2. Fetch request: Request is made to ./js/data.json
  3. Parse response: .json() method parses the response as JSON
  4. Store data: Parsed data is assigned to dashboardData
  5. Initial render: weeklyActivity() is called to display the default weekly view
The fetch happens asynchronously, so the rest of the script continues to execute while waiting for the response.

Data Structure

The JSON file contains an array of activity objects (data.json:1-104). Each object follows this schema:
{
  "title": "Work",
  "timeframes": {
    "daily": {
      "current": 5,
      "previous": 7
    },
    "weekly": {
      "current": 32,
      "previous": 36
    },
    "monthly": {
      "current": 103,
      "previous": 128
    }
  }
}

Schema Breakdown

  • title: Activity name (Work, Play, Study, Exercise, Social, Self Care)
  • timeframes: Object containing three timeframe views
    • daily: Current and previous day hours
    • weekly: Current and previous week hours
    • monthly: Current and previous month hours
  • current: Hours for the current period
  • previous: Hours for the previous period (for comparison)

Full Data Array

The complete array contains 6 activities in this order:
[
  dashboardData[0] // Work
  dashboardData[1] // Play
  dashboardData[2] // Study
  dashboardData[3] // Exercise
  dashboardData[4] // Social
  dashboardData[5] // Self Care
]
The array index corresponds directly to the order activities appear in the HTML.

DOM Element Selection

All DOM elements are selected once at the top of the file for performance (app.js:17-28):
const workCurrent       = document.querySelector('#work-current');
const workPrevious      = document.querySelector('#work-previous');
const playCurrent       = document.querySelector('#play-current');
const playPrevious      = document.querySelector('#play-previous');
const studyCurrent      = document.querySelector('#study-current');
const studyPrevious     = document.querySelector('#study-previous');
const exerciseCurrent   = document.querySelector('#exercise-current');
const exercisePrevious  = document.querySelector('#exercise-previous');
const socialCurrent     = document.querySelector('#social-current');
const socialPrevious    = document.querySelector('#social-previous');
const selfCareCurrent   = document.querySelector('#self-care-current');
const selfCarePrevious  = document.querySelector('#self-care-previous');
These references are reused throughout the application, avoiding repeated DOM queries.

Data Flow to DOM

The timeframe functions update the DOM by accessing data from the dashboardData array. Here’s how weekly data flows (app.js:62-83):
function weeklyActivity() {
    removeActiveClasses();
    weekly.classList.add("profile-card__option--active");

    workCurrent.innerText = dashboardData[0].timeframes.weekly.current;
    workPrevious.innerText = dashboardData[0].timeframes.weekly.previous;

    playCurrent.innerText = dashboardData[1].timeframes.weekly.current;
    playPrevious.innerText = dashboardData[1].timeframes.weekly.previous;

    studyCurrent.innerText = dashboardData[2].timeframes.weekly.current;
    studyPrevious.innerText = dashboardData[2].timeframes.weekly.previous;

    exerciseCurrent.innerText = dashboardData[3].timeframes.weekly.current;
    exercisePrevious.innerText = dashboardData[3].timeframes.weekly.previous;

    socialCurrent.innerText = dashboardData[4].timeframes.weekly.current;
    socialPrevious.innerText = dashboardData[4].timeframes.weekly.previous;

    selfCareCurrent.innerText = dashboardData[5].timeframes.weekly.current;
    selfCarePrevious.innerText = dashboardData[5].timeframes.weekly.previous;
}

Update Pattern

For each activity:
  1. Access the activity object by array index: dashboardData[0]
  2. Navigate to the specific timeframe: .timeframes.weekly
  3. Get the value: .current or .previous
  4. Update the DOM element: .innerText = value

Example Data Access

To display “Work” weekly current hours:
workCurrent.innerText = dashboardData[0].timeframes.weekly.current;
// dashboardData[0] = Work object
// .timeframes.weekly = Weekly timeframe
// .current = Current week value (32)
// Result: "32" is displayed in the Work card

HTML Target Elements

The HTML contains <span> elements with IDs for dynamic content (index.html:58-60):
<div class="activity-card__time">
  <p class="activity-card__hours"><span id="work-current">32</span>hrs</p>

  <p class="text--p6 text--p6--color">Last Week - <span id="work-previous">36</span>hrs</p>
</div>
The span elements:
  • Have unique IDs matching the activity and data type
  • Contain default values (weekly data)
  • Are targeted by JavaScript for updates
  • Keep surrounding text static (“hrs”, “Last Week - “)

Example: Complete Data Flow

Here’s the complete flow when a user clicks “Monthly”:
  1. User action: Click Monthly button
  2. Event listener: Triggers monthlyActivity() (app.js:113)
  3. Data access: Function reads from dashboardData array
    workCurrent.innerText = dashboardData[0].timeframes.monthly.current;
    // Accesses: {"title": "Work", "timeframes": {"monthly": {"current": 103}}}
    // Returns: 103
    
  4. DOM update: .innerText updates the span content
  5. Visual result: Work card shows “103hrs” instead of “32hrs”
All 6 activity cards update simultaneously when switching timeframes, creating a smooth, synchronized UI update.

Performance Considerations

  1. Single fetch: Data is loaded once on page load
  2. Cached references: DOM elements are selected once and reused
  3. No redundant queries: Array access is direct via index
  4. Synchronous updates: All DOM updates happen in a single function call
  5. No layout thrashing: Reading and writing operations are batched

Error Handling

The current implementation doesn’t include error handling for the fetch operation. In production, you should add .catch() to handle network errors:
fetch('./js/data.json')
    .then(response => response.json())
    .then(data => {
        dashboardData = data;
        weeklyActivity();
    })
    .catch(error => {
        console.error('Failed to load data:', error);
        // Display error message to user
    });

Build docs developers (and LLMs) love