Making the JADA Maintenance Hub Dashboard Cards Interactive: Routing UI State to Tab Navigation
What Was Done
The JADA Maintenance Hub dashboard's "Total Tasks" summary card was displaying aggregate data but wasn't actionable—clicking it did nothing. We implemented a clickable card pattern that routes users directly to the Systems tab where the detailed task table lives. This required modifying the S3-hosted dashboard HTML, updating CSS for interactive states, and invalidating the CloudFront distribution to push changes to production.
Technical Details: The Problem
The dashboard's index.html file (stored in the maintenance S3 bucket) rendered four summary cards at the top of the page: Total Tasks, Total Systems, Active Alerts, and Last Service. The Total Tasks card showed an aggregate count (e.g., "82") but lacked affordances—no cursor change, no click handler, no visual feedback. Users couldn't intuit that the summary card was a gateway to detailed task data.
The architecture follows a common single-page app pattern: a tabbed interface with five tabs (Dashboard, Systems, History, Logs, Settings), each containing different data views. The task list itself lives in the systems tab as an HTML table. The challenge was wiring the summary card's click event to the existing tab-switching mechanism without duplicating logic or breaking the current navigation flow.
Infrastructure & File Locations
- Source File:
s3://maintenance-hub-assets/index.html— the compiled dashboard hosted in S3 - CloudFront Distribution:
maintenance.queenofsandiego.com— the public-facing CDN endpoint backed by the S3 bucket - Tab Navigation Function:
switchTab(tabName)— existing JavaScript function that handles tab switching logic - Task Table Container: Located within the element with
data-tab="systems"attribute
Implementation Steps
1. Downloading and Analyzing the Current Dashboard
The first step was pulling the current index.html from S3 to inspect the HTML structure and JavaScript logic:
aws s3 cp s3://maintenance-hub-assets/index.html ./maintenance_index.html
We searched for the tab navigation logic to understand how switchTab() works and confirmed that all tab containers use consistent data-tab attributes. The Systems tab is identified by data-tab="systems" and contains the task table markup.
2. Locating the Total Tasks Card Markup
We searched the HTML for the "Total Tasks" card text to pinpoint its exact structure. The card was a <div> with class info-card, displaying a title and numeric count. Unlike button or anchor elements, it wasn't semantic for interaction.
3. HTML Structure Modification
We wrapped the Total Tasks card in a clickable container and added an onclick handler:
<div class="info-card info-card-link" onclick="switchTab('systems')">
<div class="card-title">Total Tasks</div>
<div class="card-value">82</div>
</div>
The new class info-card-link signals to CSS that this card is interactive, allowing us to style it distinctly from read-only summary cards.
4. CSS for Interactive State
We added styles for the clickable card to provide visual feedback:
.info-card-link {
cursor: pointer;
transition: all 0.2s ease;
}
.info-card-link:hover {
background-color: #f5f5f5;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
transform: translateY(-2px);
}
.info-card-link:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}
These styles provide three layers of feedback: hover lift (indicating clickability), shadow enhancement (depth), and active state (press confirmation). The cursor: pointer is critical—it's the first affordance users scan for.
Why This Approach
Reusing existing tab logic: Rather than creating a new route or modal, we leveraged the already-tested switchTab('systems') function. This minimizes the surface area for bugs and keeps navigation consistent across the app.
Semantic naming: The info-card-link class name communicates intent. Future developers can quickly identify which cards are interactive without reading function calls.
Progressive enhancement: The card still displays correctly if JavaScript fails; it's just not clickable. This is a minor UX degradation, not a broken feature.
Performance: Adding one class and a simple onclick handler has negligible performance impact. No new event listeners, delegators, or DOM queries were introduced.
Deployment: S3 and CloudFront
After modifying the HTML and CSS, we uploaded the updated file back to S3:
aws s3 cp ./maintenance_index.html s3://maintenance-hub-assets/index.html --content-type "text/html; charset=utf-8"
The --content-type flag ensures browsers treat the file as HTML with UTF-8 encoding, critical for proper rendering.
However, uploading to S3 doesn't immediately update the public site. CloudFront caches the file at edge locations. To force a refresh, we invalidated the CloudFront distribution:
aws cloudfront create-invalidation --distribution-id E1234ABCD5678 --paths "/index.html"
The distribution ID (E1234ABCD5678 in this example—your actual ID differs) corresponds to the maintenance.queenofsandiego.com subdomain. Invalidation typically propagates within 60 seconds; within that window, users may see cached versions. For critical updates, we could lower CloudFront's default TTL (Time To Live) from the typical 24 hours to 5 minutes, accepting slightly higher origin load in exchange for faster propagation.
Verification
After invalidation, we navigated to maintenance.queenofsandiego.com in a fresh incognito session (to bypass browser cache) and confirmed:
- The Total Tasks card displays normally on the Dashboard tab
- Hovering shows the gray background and lift effect
- Clicking the card switches the view to the Systems tab
- The task table is visible and searchable
What's Next
This pattern should be applied to the other summary cards (Total Systems, Active Alerts) if they also link to relevant detail views. We should also consider:
- Accessibility: Adding
role="button"andtabindex="0"to the card div for keyboard navigation and screen readers. - Analytics: Wiring a click event to log when users navigate from the dashboard summary to detailed views—useful for understanding