User Interface medium complexity mobile
1
Dependencies
1
Dependents
1
Entities
0
Integrations

Description

Displays a personal milestone achievement (e.g., first session, 100 hours, 50 people helped) as an animated badge with an icon, title, and short description. Badges are revealed with a pop animation and include full VoiceOver/TalkBack support describing what the milestone represents.

Feature: Annual Impact Summary (Wrapped)

milestone-badge-widget

Summaries

The Milestone Badge Widget directly drives peer mentor retention and motivation by visually celebrating key achievements such as first sessions, cumulative hours reached, and numbers of people helped. Recognising effort with animated, personalised badges transforms abstract volunteering statistics into tangible moments of pride, increasing the likelihood that mentors remain active and engaged over the long term. This reduces churn costs and sustains programme capacity without additional recruitment spend. Full accessibility support ensures the organisation meets inclusivity obligations and widens the pool of volunteers who can participate effectively.

This is a self-contained medium-complexity mobile UI widget with a single external dependency on the wrapped-animation-controller. Development effort is moderate, primarily covering the animation sequencing, locked/unlocked state logic, and VoiceOver/TalkBack accessibility announcements. Testing must cover animation timing, screen reader output validation on both iOS and Android, and visual regression for badge states. No backend dependency exists, so scheduling is decoupled from API work.

Risk is low but accessibility testing on real devices should be planned explicitly to avoid late-stage rework.

MilestoneBadgeWidget accepts a Milestone data model and an optional isNew flag controlling whether the reveal animation fires on mount. It delegates animation lifecycle to wrapped-animation-controller, calling playRevealAnimation() post-frame via WidgetsBinding. getAccessibilityAnnouncement() constructs a semantics string combining milestone title and description, surfaced via Flutter's Semantics widget with liveRegion: true for dynamic announcements. Locked state renders a greyed overlay with reduced opacity.

The widget is stateful only for animation; milestone state is owned externally. Ensure animation controller is disposed to prevent memory leaks.

Responsibilities

  • Render milestone badge with icon, title, and description
  • Animate badge reveal on first display
  • Announce milestone details to screen readers
  • Handle locked/unlocked visual states

Interfaces

MilestoneBadgeWidget({required Milestone milestone, bool isNew = false})
playRevealAnimation(): void
getAccessibilityAnnouncement(): String

Relationships

Dependencies (1)

Components this component depends on

Dependents (1)

Components that depend on this component

Related Data Entities (1)

Data entities managed by this component