```html

Making Dashboard Cards Actionable: Wiring UI Elements to Tab Navigation in a Static S3-Hosted Maintenance Hub

Problem Statement

The JADA Maintenance Hub dashboard displays a "Total Tasks" information card showing task count (e.g., "82"), but it was purely informational—clicking it did nothing. Users needed a direct path from the dashboard summary to the detailed task list. The card should behave as a clickable element that programmatically switches the dashboard view to the Tasks tab, eliminating an extra click and making the dashboard more intuitive.

What Was Done

We converted a static HTML info-card element into an interactive, clickable element that triggers tab navigation by:

  • Identifying the card's DOM structure and its parent tab system
  • Adding semantic onclick handlers that invoke the existing switchTab() function
  • Styling the card with hover states and cursor changes to signal interactivity
  • Deploying the updated HTML to S3 and invalidating the CloudFront distribution cache

Technical Details: Architecture and Implementation

File Locations and Storage Strategy

The Maintenance Hub is hosted entirely on AWS S3 with CloudFront distribution caching. The primary file modified was:

s3://jada-maintenance-hub/index.html

This single HTML file contains all dashboard markup, CSS, and JavaScript. It's served through CloudFront distribution (fetched via CLI inspection, not hardcoded here) to ensure low-latency access and cache control. The file is downloaded from S3, edited locally, then re-uploaded, with CloudFront cache invalidation to serve the updated version immediately.

Tab Navigation Architecture

The dashboard uses a straightforward tab-switching pattern:

  • Tab Definition: Each tab has a data-tab attribute (e.g., data-tab="systems", data-tab="tasks", data-tab="overview")
  • JavaScript Handler: A global switchTab(tabName) function hides all tab content, then reveals the matching tab by ID
  • Tab Content Storage: Task table and system maintenance records are rendered in separate <div id="tasks"> and <div id="systems"> containers

The existing switch logic uses element visibility toggling—no AJAX or route changes, just DOM manipulation. This pattern is efficient for a static dashboard and avoids dependency on routing libraries.

Card Interactivity Implementation

The original "Total Tasks" card markup looked like:

<div class="info-card">
  <h3>Total Tasks</h3>
  <p class="stat-value">82</p>
</div>

We wrapped this in an interactive layer and added an onclick handler:

<div class="info-card info-card-link" onclick="switchTab('systems')">
  <h3>Total Tasks</h3>
  <p class="stat-value">82</p>
</div>

Why this approach: We added a second CSS class (info-card-link) rather than modifying the base info-card style to maintain backward compatibility. Other cards on the dashboard (e.g., engine hours, fuel status) remain non-interactive. This keeps the codebase maintainable—future developers can instantly identify which cards are actionable by class name.

CSS Styling for Interaction Affordance

Static styling alone doesn't signal interactivity. We added hover and cursor states:

.info-card-link {
  cursor: pointer;
  transition: all 0.2s ease;
  border: 2px solid transparent;
}

.info-card-link:hover {
  background-color: #f5f5f5;
  border-color: #007bff;
  box-shadow: 0 4px 8px rgba(0, 123, 255, 0.2);
}

.info-card-link:active {
  background-color: #e8e8e8;
  transform: scale(0.98);
}

Why these specific styles: The 0.2s transition provides tactile feedback without feeling laggy. The border change and shadow lift create visual depth, signaling that the element is interactive. The scale(0.98) on active state mimics a button press, which is familiar to users. These micro-interactions cost nothing in performance but dramatically improve UX.

Infrastructure and Deployment Pipeline

S3 Upload Process

After editing the local file, deployment uses the AWS CLI:

aws s3 cp /path/to/maintenance_index.html s3://jada-maintenance-hub/index.html --acl public-read

The --acl public-read flag ensures CloudFront can access the file. S3 bucket policies restrict direct public access (users must go through CloudFront), but CloudFront's origin access identity (OAI) needs read permissions.

CloudFront Cache Invalidation

After upload, we invalidate the CloudFront distribution to ensure users see the updated file immediately:

aws cloudfront create-invalidation --distribution-id [DISTRIBUTION_ID] --paths "/*"

Why invalidate: CloudFront caches index.html with a TTL (typically 86400 seconds/24 hours). Without invalidation, users hitting the site within 24 hours would see the old cached version. Invalidating the /* path clears all objects, ensuring everyone gets the fresh HTML on next page load.

Cost consideration: Each invalidation is metered; AWS allows 3000/month free, then ~$0.005 per path. Invalidating /* counts as one path, so cost is negligible for this use case.

Key Decisions and Trade-offs

Why Inline onclick Instead of Event Listeners

We used inline onclick="switchTab('systems')" instead of attaching event listeners via JavaScript. Reasons:

  • Single-file architecture: The dashboard is one HTML file with no bundler or module system. Event listener attachment would require wrapping it in a <script> tag that runs after DOM render—simpler to use inline handlers.
  • Auditability: Developers reading the HTML can instantly see which elements are interactive and where they navigate.
  • No JavaScript execution dependencies: If JavaScript fails to load (rare, but possible in high-latency scenarios), inline handlers fail gracefully—the page still loads and is readable.

Why Modify a Class, Not a Style

We added info-card-link rather than changing the base .info-card styles. This prevents unintended side effects—if a developer later adds another info-card (e.g., "Last Maintenance Date"), they can choose whether it's interactive by including the class or not. Single responsibility principle applied to CSS.

Why switchTab