Skip to main content

Visual Overview

The Dashboard module is the central analytical hub of the application. It employs a Tabbed Layout strategy where users can switch between different metrics using a custom floating bottom navigation bar. Each sub-screen (Phone Usage, Unlocks, Scroll, Notifications) follows a consistent vertical layout pattern:
  1. Metric Header: A high-level summary of the current data.
  2. Interactive Heatmap: A calendar-based visualization of intensity over time.
  3. Period Selector: A segmented control to toggle between Daily, Weekly, and Monthly views.
  4. Ranked List: A of apps contributing to the metric, grouped into cohesive visual cards.

UI Structure

The module is organized as a single visual unit driven by DashboardTabs.
  • Root: DashboardTabs
    • Navigation: A floating Row with “Fan-In” animations using AnimatedVisibility.
    • Scaffold: ScreenScaffold providing a and centralized snackbar handling.
    • Content Area: AnimatedContent container that transitions between:
      • PhoneUsageScreen: Focuses on time-based duration.
      • UnlocksScreen: Focuses on frequency of app opens.
      • ScrollDetailScreen: Focuses on physical distance (meters/pixels).
      • NotificationsScreen: Focuses on alert volume.
    • Shared Components:
      • DashboardHeatmap: Wraps InteractiveCalendarHeatmap.
      • AppListItemCard: A -heavy component that handles grouping (Top, Middle, Bottom, Single) to create “connected” card visuals.
      • RemovedAppsCard: An aggregate entry for uninstalled apps that still have historical data.

State & Interaction

State Management

The UI follows the pattern. Each screen observes a UiState (e.g., NotificationsUiState) emitted by a Hilt-injected ViewModel.
  • Inputs: The screens accept a UiState data class containing the heatmap data, app list, and current selection parameters.
  • Dynamic Visibility: The floating bottom bar visibility is tied to scroll gestures via a NestedScrollConnection, hiding on scroll-down and appearing on scroll-up.

Event Bubbling

is used for all user interactions:
  • Date Selection: Clicking a cell in the heatmap updates the selectedDate in the ViewModel, which triggers a of the app list.
  • Limit Setting: Clicking the “Limit” icon on any app row triggers a SetLimitBottomSheet via the ViewModel’s state.
  • Navigation: Clicking an app row navigates to the AppDetailRoute using the provided NavController.

Design System Usage

This module heavily utilizes the application’s custom :
  • Typography: Uses BodyFontFamily with ExtraBold weights for primary metrics.
  • Shapes: Employs MaterialShapes (Expressive API) for the back button, providing randomized geometric variety (Clover, Star, etc.) on each view.
  • Grouping: Uses a custom GroupPosition logic to apply specific corner radii to items in a list, making them appear as a single “connected” container.
  • Color: Heatmap intensity is mapped to a gradient from surfaceContainerHighest to primary.

Onboarding & Tutorials

The module integrates a TutorialScaffold that provides a “Spotlight” walkthrough.
  • Targeting: Components use the Modifier.spotlightTarget(TutorialTargetId) to identify themselves to the tutorial overlay.
  • Sequencing: Each dashboard tab has a unique List<TutorialStep> defining the copy and order of the walkthrough.
  • Auto-Scroll: The tutorial system can trigger animateScrollToItem on the LazyColumn to ensure the spotlighted element is in view.

Preview & Testing

Components are designed to be stateless where possible to support Previews.
  • Test Tags: Key interactive elements like the PeriodSelector and LimitIcon use specific target IDs for automated UI testing.
  • Empty States: A PremiumEmptyState component is used when no data is available, providing a visual call-to-action.
Last modified on January 22, 2026