Making Dashboard Cards Interactive: Linking the JADA Maintenance Hub "Total Tasks" Card to the Systems Tab

What Was Done

The JADA Maintenance Hub dashboard displays a "Total Tasks" card showing an aggregate count (e.g., "Total Tasks 82"), but this card was purely informational. Users viewing the dashboard who wanted to see the actual task list had to manually navigate to the Systems tab. This required an additional click and created friction in the UX flow. The task was to make this card clickable and wire it to automatically switch to the Systems tab, eliminating the extra navigation step.

Technical Details

File Location and Storage

The maintenance hub is deployed as a static site served from an S3 bucket. The primary file was:

  • s3://jada-maintenance-hub/index.html — Contains the dashboard markup, styling, and tab navigation logic

The file is not stored in the local Git repository; it lives exclusively in S3 and is served through a CloudFront distribution for caching and CDN performance. This architecture keeps the maintenance dashboard decoupled from the main site infrastructure while allowing rapid iteration on static assets.

Understanding the Tab Navigation System

The maintenance hub uses a tab-based interface with the following structure:

  • Tab Navigation: Tabs are defined with a data-tab attribute (e.g., data-tab="systems", data-tab="schedules")
  • Switch Function: A JavaScript function switchTab(tabName) handles the logic to show/hide tab content and update the active tab state
  • Task Rendering: The Systems tab contains the task table which is populated dynamically from the dashboard state

The key insight was that the existing switchTab() function already had all the necessary logic to switch tabs; we only needed to wire the card click event to invoke it with the correct parameter.

Making the Card Clickable

The "Total Tasks" card was initially a static <div> with the class info-card. To make it interactive without breaking the existing layout, we:

  1. Added an onclick handler: Set onclick="switchTab('systems')" on the card element, passing the tab identifier as a string
  2. Updated CSS styling: Added a new class info-card-link to provide visual feedback that the card is clickable
  3. CSS properties for interactivity:
    • cursor: pointer; — Changes the cursor to a hand icon on hover
    • transition: transform 0.2s ease, box-shadow 0.2s ease; — Smooth animation for hover feedback
    • :hover state with slight scale transform and enhanced shadow — Provides tactile visual feedback

Example CSS added to the stylesheet:

.info-card-link {
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.info-card-link:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
}

Infrastructure and Deployment

S3 Bucket and CloudFront Distribution

The maintenance hub is hosted on:

  • S3 Bucket: jada-maintenance-hub
  • CloudFront Distribution: A distribution pointing to the S3 bucket origin, with the maintenance subdomain configured via Route53 CNAME/alias records

The CloudFront distribution provides edge caching, which means that after uploading the updated index.html` to S3, the file must be invalidated in the CloudFront cache to ensure users receive the latest version immediately.

Deployment Steps

The deployment process involved three steps:

  1. Download the current version from S3:
    aws s3 cp s3://jada-maintenance-hub/index.html ./index.html
  2. Make the code edits locally (add onclick handler and CSS class)
  3. Upload the updated file back to S3:
    aws s3 cp ./index.html s3://jada-maintenance-hub/index.html --content-type "text/html"
  4. Invalidate the CloudFront cache:
    aws cloudfront create-invalidation --distribution-id DISTRIBUTION_ID --paths "/*"

Note: The DISTRIBUTION_ID is a specific alphanumeric identifier for the CloudFront distribution serving the maintenance hub. This ID was obtained by listing CloudFront distributions and matching against the maintenance subdomain.

Key Decisions and Rationale

Why Not Use a Routing Library?

The maintenance hub is a lightweight, single-page application with a simple tab-switching mechanism. Rather than introducing a JavaScript routing library (e.g., Vue Router, React Router), the existing native implementation with a switchTab() function was leveraged. This keeps the application lean and avoids unnecessary dependencies.

Why CloudFront Invalidation?

CloudFront caches content at edge locations with a default TTL (Time To Live). Without invalidation, end users might see the old version of the dashboard for up to the TTL duration. By issuing an invalidation command immediately after uploading to S3, we force CloudFront to fetch the latest version from the origin bucket, ensuring users see the update within seconds.

CSS Class Approach Over Inline Styles

Rather than adding inline styles directly to the card element, a new CSS class info-card-link was created. This follows separation of concerns: markup is kept clean and styling logic lives in the stylesheet. It also makes future bulk updates easier—any card can have the "link" behavior by adding the class.

What's Next

The immediate next steps include:

  • User testing: Verify that the card is obviously clickable to end users (Sergio and other crew) and that the tab switch is responsive
  • Consistency audit: Review other info cards on the dashboard to determine if they should also be interactive (e.g., "Engine Hours" card linking to Engine Systems tab)
  • Analytics: Track clicks on the card using event listeners to understand user behavior and validate the UX improvement
  • Accessibility: Ensure the card meets WCAG standards by adding proper ARIA labels and keyboard navigation support (e.g., Tab + Enter to activate)

The change is minimal and backward-compatible—existing functionality is preserved, and the new interactivity is additive. The deployment is live and accessible immediately after CloudFront invalidation completes.