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
- Initialize empty array:
dashboardData is declared as an empty array
- Fetch request: Request is made to
./js/data.json
- Parse response:
.json() method parses the response as JSON
- Store data: Parsed data is assigned to
dashboardData
- 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:
- Access the activity object by array index:
dashboardData[0]
- Navigate to the specific timeframe:
.timeframes.weekly
- Get the value:
.current or .previous
- 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”:
- User action: Click Monthly button
- Event listener: Triggers
monthlyActivity() (app.js:113)
- Data access: Function reads from
dashboardData array
workCurrent.innerText = dashboardData[0].timeframes.monthly.current;
// Accesses: {"title": "Work", "timeframes": {"monthly": {"current": 103}}}
// Returns: 103
- DOM update:
.innerText updates the span content
- 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
- Single fetch: Data is loaded once on page load
- Cached references: DOM elements are selected once and reused
- No redundant queries: Array access is direct via index
- Synchronous updates: All DOM updates happen in a single function call
- 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
});