Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Cristiang1021/ErgoKawsay/llms.txt

Use this file to discover all available pages before exploring further.

Seeing tangible evidence of effort is one of the most powerful motivators for sustaining healthy habits. The Progress screen surfaces a clear, at-a-glance view of every session a teacher has completed — exercises, active breaks, emotions recorded, and calendar days the app was opened — all sourced entirely from on-device storage. No account, no cloud sync, and no personal data ever leaves the device. The screen supports pull-to-refresh so that stats update instantly after a session completes in another part of the app. An embedded variant (embedded: true) is also available for rendering Progress inline within the home tab without a separate navigation push.

Tracked Metrics

Exercises Completed

Running total of full exercise sessions the teacher has finished. Incremented by storage.recordExerciseCompleted() at the end of each guided exercise flow.

Active Breaks Completed

Running total of completed active break sequences. Incremented by storage.recordActiveBreakCompleted() when a break sequence reaches its final step.

Emotions Recorded

Total number of emotion diary entries across all sessions, derived from ProgressData.totalEmotionsRecorded (the sum of all values in the emotionsRecorded map). Individual emotion counts are also shown in the emotion history list below the stat tiles.

Days Used

Number of unique calendar days on which the app was opened, stored as YYYY-MM-DD formatted date strings in ProgressData.usageDays. Computed as usageDays.length.

ProgressData Model

The ProgressData class is the single source of truth for all progress information. It is immutable (all mutations return a new instance via copyWith) and fully JSON-serializable.
class ProgressData {
  final int exercisesCompleted;            // total completed exercise sessions
  final int activeBreaksCompleted;         // total completed active break sequences
  final Map<String, int> emotionsRecorded; // emotionId → count
  final List<String> usageDays;            // unique dates, e.g. ["2025-01-15", ...]
  final DateTime? lastUsedDate;            // most recent app-open timestamp

  // Derived getter
  int get totalEmotionsRecorded =>
      emotionsRecorded.values.fold(0, (sum, count) => sum + count);

  factory ProgressData.empty() => const ProgressData(
        exercisesCompleted: 0,
        activeBreaksCompleted: 0,
        emotionsRecorded: {},
        usageDays: [],
      );
}
The model serializes to JSON via toJson() and is reconstructed with ProgressData.fromJson(). Missing or null fields fall back to their zero-value defaults, making forward-compatibility safe when new fields are added.

Recording Actions

All write operations go through StorageService, which reads the current ProgressData, applies the increment, and immediately writes the updated object back to SharedPreferences. Every method returns the updated ProgressData so callers can react to the new state without a second read.
// Increment exercises completed
final updated = await storage.recordExerciseCompleted();

// Increment active breaks completed
final updated = await storage.recordActiveBreakCompleted();

// Increment the count for a specific emotion
final updated = await storage.recordEmotion('joy'); // emotionId string

// Record today as an app-open day (deduplicates automatically)
final updated = await storage.recordAppOpen();
recordAppOpen() converts usageDays to a Set<String> internally before adding today’s key, then converts back to List<String> before saving. Calling it multiple times on the same day will not inflate the usageDays count.

Persistence

Progress data is serialized to JSON and stored in SharedPreferences under the key AppConstants.keyProgress ("progress").
// Direct read (returns ProgressData.empty() if no data exists yet)
final progress = storage.getProgress();

// Direct write (used internally by all record* methods)
await storage.saveProgress(progressData);
The ProgressData.toJson() map contains the following keys:
JSON KeyDart TypeDescription
exercisesCompletedintTotal exercise sessions
activeBreaksCompletedintTotal active break sequences
emotionsRecordedMap<String, int>Per-emotion counts keyed by emotionId
usageDaysList<String>Unique YYYY-MM-DD date strings
lastUsedDateString?ISO 8601 timestamp or null

Emotion History

Below the four stat tiles, the screen renders a scrollable list of every emotion the teacher has logged, matched to a localized name from LocalDataRepository.instance.emotions. Each row displays the emotion’s name (in Spanish or Kichwa depending on the current locale) and a pill badge showing its count. If no emotions have been recorded yet, a “No data” placeholder is shown instead. The emotionsRecorded field is a Map<String, int> where each key is an emotionId string and the value is the number of times that emotion has been recorded.

Route

Navigate to the Progress screen via the named route /progress. The screen can also be embedded directly within a parent Scaffold by constructing it with embedded: true.

Build docs developers (and LLMs) love