From 40fd63e74808bad171f11812bbd0301d8b8d3a59 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Fri, 27 Feb 2026 22:13:50 -0800 Subject: [PATCH] =?UTF-8?q?feat(gamification):=20integrate=20gamification?= =?UTF-8?q?=20into=20app=20=E2=80=94=20badge=20celebration=20overlay,=20hi?= =?UTF-8?q?story=20stats+badges=20tabs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/ChronoMind/App/ChronoMindApp.swift | 34 +++++++++++++------ .../Views/History/HistoryView.swift | 33 ++++++++++++++++++ 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/ios/ChronoMind/App/ChronoMindApp.swift b/ios/ChronoMind/App/ChronoMindApp.swift index f2eaa08..eed868f 100644 --- a/ios/ChronoMind/App/ChronoMindApp.swift +++ b/ios/ChronoMind/App/ChronoMindApp.swift @@ -7,20 +7,34 @@ import WidgetKit struct ChronoMindApp: App { @StateObject private var timerStore = TimerStore() @StateObject private var notificationManager = CMNotificationManager.shared + @StateObject private var gamification = GamificationStore.shared var body: some Scene { WindowGroup { - ContentView() - .environmentObject(timerStore) - .environmentObject(notificationManager) - .preferredColorScheme(.dark) - .task { - notificationManager.registerCategories() - await notificationManager.requestPermission() - } - .onReceive(NotificationCenter.default.publisher(for: .chronoMindTimersDidChange)) { _ in - WidgetCenter.shared.reloadAllTimelines() + ZStack { + ContentView() + .environmentObject(timerStore) + .environmentObject(notificationManager) + .environmentObject(gamification) + .preferredColorScheme(.dark) + .task { + notificationManager.registerCategories() + await notificationManager.requestPermission() + } + .onReceive(NotificationCenter.default.publisher(for: .chronoMindTimersDidChange)) { _ in + WidgetCenter.shared.reloadAllTimelines() + } + + // Badge celebration overlay + if let badge = gamification.newBadge { + BadgeCelebrationOverlay(badge: badge) { + gamification.clearNewBadge() + } + .transition(.opacity) + .zIndex(100) } + } + .animation(.easeInOut, value: gamification.newBadge != nil) } } } diff --git a/ios/ChronoMind/Views/History/HistoryView.swift b/ios/ChronoMind/Views/History/HistoryView.swift index f29ddd3..a8441a6 100644 --- a/ios/ChronoMind/Views/History/HistoryView.swift +++ b/ios/ChronoMind/Views/History/HistoryView.swift @@ -10,6 +10,7 @@ struct HistoryView: View { enum HistorySegment: String, CaseIterable { case recent = "Recent" case stats = "Stats" + case badges = "Badges" } private var completedTimers: [CMTimer] { @@ -39,6 +40,8 @@ struct HistoryView: View { recentList case .stats: statsView + case .badges: + badgesView } } } @@ -87,6 +90,20 @@ struct HistoryView: View { private var statsView: some View { ScrollView { VStack(spacing: CMSpacing.lg) { + // Streak card + StreakCard() + + // Focus score + let focusScore = GamificationEngine.calculateFocusScore(timers: store.timers) + FocusScoreCard(score: focusScore) + + // Weekly summary card (shareable) + let summary = GamificationEngine.generateWeeklySummary( + timers: store.timers, + streak: GamificationStore.shared.streak + ) + WeeklySummaryCard(summary: summary) + // Summary cards let allTimers = store.timers let completed = allTimers.filter { $0.state == .completed }.count @@ -166,6 +183,22 @@ struct HistoryView: View { .padding(.bottom, CMSpacing.xxl) } } + + // MARK: - Badges View + + private var badgesView: some View { + ScrollView { + VStack(spacing: CMSpacing.lg) { + // Streak card (compact) + StreakCard() + + // Badge grid + BadgeGridView() + } + .padding(.horizontal, CMSpacing.lg) + .padding(.bottom, CMSpacing.xxl) + } + } } // MARK: - Stat Card