Making the JADA Maintenance Dashboard Stats Cards Interactive: Bridging UI and Navigation State
What Was Done
The JADA Maintenance Hub dashboard displays a "Total Tasks" stat card showing an aggregated count of all tracked maintenance items across the vessel. Previously, this card was purely informational—clicking it did nothing. The requirement was to make it actionable: clicking the "Total Tasks" card should navigate the user directly to the Tasks tab where the detailed task list lives, improving UX by reducing the cognitive load of finding where tasks are displayed.
This involved modifying the dashboard HTML served from S3, updating CSS for interactive states (hover feedback), and wiring the click event to the existing tab-switching logic without breaking the current navigation architecture.
Technical Details
The Challenge: DOM Structure vs. Functionality
The maintenance hub index.html (stored in S3 at the path reserved for the maintenance subdomain) contains multiple dashboard sections rendered via tabs. The "Total Tasks" card existed as a static `
The core issue: the stat card had no connection to the navigation logic. The solution required three changes:
- HTML Structure: Convert the static card div into a clickable element (semantically, a button-styled div with proper ARIA attributes would be ideal, but given the existing structure, wrapping or adding an onclick handler was the pragmatic choice)
- JavaScript: Wire the click event to call the existing `switchTab('systems')` function
- CSS: Add visual feedback via hover states to signal interactivity
Implementation: The Edit
The file path for the maintenance hub dashboard:
s3://jada-maintenance-hub/index.html
Workflow:
- Download from S3: Pulled the current index.html from the S3 bucket to inspect the structure and locate the Total Tasks card markup.
- Locate the Card Markup: Found the card element with id or class selector matching the "Total Tasks" display. The card was a straightforward div with child elements for the label and count.
- Add onclick Handler: Modified the card div to include `onclick="switchTab('systems')"`, tapping into the existing tab-switching function already present in the page's JavaScript.
- Add CSS Class: Created a new CSS class `.info-card-link` to differentiate clickable cards from static ones, applying cursor pointer, hover background color change, and a subtle transition for polish.
CSS addition:
.info-card-link {
cursor: pointer;
transition: background-color 0.2s ease, box-shadow 0.2s ease;
}
.info-card-link:hover {
background-color: rgba(0, 0, 0, 0.05);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
HTML change (conceptual):
<div class="info-card info-card-link" onclick="switchTab('systems')">
<div class="card-label">Total Tasks</div>
<div class="card-value">82</div>
</div>
Infrastructure and Deployment
S3 Bucket and CloudFront Integration
The maintenance hub is served through a CloudFront distribution, with S3 as the origin. This architecture provides:
- Edge Caching: Static HTML cached at CloudFront edge locations for sub-100ms global delivery
- Origin Shield: Reduces origin load spikes when cache expires
- Gzip Compression: Automatic compression of HTML/CSS/JS payloads
After uploading the modified index.html to the S3 bucket, a cache invalidation was required:
aws cloudfront create-invalidation \
--distribution-id [DISTRIBUTION_ID] \
--paths "/*"
This invalidation purges all cached objects, forcing CloudFront to fetch the updated index.html on the next request. The invalidation typically propagates globally within 30–60 seconds.
DNS and Subdomain Routing
The maintenance.jada subdomain (or similar) is configured in Route53 as a CNAME record pointing to the CloudFront distribution domain. This remains unchanged; the infrastructure layer requires no modification.
Key Decisions
Why Reuse the Existing switchTab() Function?
The maintenance hub already had a robust tab-switching mechanism with state management, CSS class toggling, and scroll positioning. Rather than introducing duplicate navigation logic, leveraging the existing function kept the codebase DRY and ensured consistency with other navigation patterns in the app.
CSS vs. Inline Styles
New CSS classes were added to the stylesheet rather than using inline styles. This approach:
- Enables media queries if responsive behavior is needed later
- Keeps presentation logic separate from markup
- Allows hover and other pseudo-class styling (impossible with inline styles)
- Makes future design tweaks centralized and easier to maintain
Hover Feedback over Active State
The card uses a hover state rather than an "active" or "focus" state because clicking it immediately navigates to the Tasks tab, which becomes the new active tab. The visual feedback on hover signals interactivity before the click, which is the UX pattern users expect from clickable elements.
Testing and Validation
Post-deployment validation steps:
- Cache Bypass: Tested with `?cache-bust=1` query parameter to ensure CloudFront served the fresh version
- Cross-Device: Verified on mobile, tablet, and desktop to ensure the larger touch target on mobile was sufficient
- Tab State: Confirmed that clicking the card switched the active tab, scrolled to the task table, and that the Tasks tab styling reflected as "active"
- Accessibility: Noted that a future enhancement could add `role="button"` and `tabindex="0"` to the div for keyboard navigation support, plus an `aria-label` for screen readers
What's Next
This change is the first step toward making dashboard stats actionable. Future enhancements could include:
- Other Stat Cards: Apply the same pattern to other cards (e.g., "Overdue Maintenance" → filters the Tasks tab to show overdue items)
- Keyboard Navigation: Add ARIA attributes and keyboard event handling for a11y compliance
- Analytics Instrumentation: Track which stat cards are clicked most often to inform dashboard redesign priorities
- Deep Linking: Consider URL-based tab state (e.g., `#systems`) so users can share direct links to specific tabs
Summary
By making the Total Tasks card clickable and wired to the existing tab navigation, we've improved the dashboard's discoverability and reduced friction for users who want to drill down into task