analytics(deeplink): route report notification tap to its report (KC-51 ph4c)
Completes deep-link routing (goal #7): AnalyticsDeepLink is Identifiable; a tapped weekly/monthly report notification is consumed in ContentView on launch/active and presents AnalyticsView opened to that area. Core round-trip re-verified standalone; SwiftUI wiring needs an Xcode build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ import Foundation
|
||||
/// Format: wenza://analytics → overview
|
||||
/// wenza://analytics/weekly/<yyyy-MM-dd> → a weekly report
|
||||
/// wenza://analytics/monthly/<yyyy-MM> → a monthly report
|
||||
enum AnalyticsDeepLink: Equatable {
|
||||
enum AnalyticsDeepLink: Equatable, Identifiable {
|
||||
case overview
|
||||
case weekly(weekStartKey: String)
|
||||
case monthly(monthKey: String)
|
||||
@@ -15,6 +15,8 @@ enum AnalyticsDeepLink: Equatable {
|
||||
static let scheme = "wenza"
|
||||
static let host = "analytics"
|
||||
|
||||
var id: String { stringValue }
|
||||
|
||||
/// Stable userInfo key carried on notifications.
|
||||
static let userInfoKey = "kisani.analytics.deeplink"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ struct ContentView: View {
|
||||
return 0
|
||||
}()
|
||||
@State private var showQuickAddTask = false
|
||||
@State private var analyticsLink: AnalyticsDeepLink?
|
||||
@StateObject private var tabState = FloatingTabState()
|
||||
@ObservedObject private var shortcuts = ShortcutHandler.shared
|
||||
@ObservedObject private var tutorial = TutorialManager.shared
|
||||
@@ -108,6 +109,7 @@ struct ContentView: View {
|
||||
// Backfill any missing analytics reports (idempotent), then notify.
|
||||
let generated = AnalyticsService.shared.reconcile(using: workoutVM)
|
||||
NotificationManager.shared.scheduleAnalyticsReports(generated)
|
||||
if let link = NotificationManager.shared.consumePendingAnalyticsDeepLink() { analyticsLink = link }
|
||||
// Pull workouts from Health, then reschedule so a detected workout updates reminders.
|
||||
Task {
|
||||
await workoutVM.syncFromHealthKit()
|
||||
@@ -166,6 +168,11 @@ struct ContentView: View {
|
||||
.presentationDetents([.height(150)])
|
||||
.presentationDragIndicator(.visible)
|
||||
}
|
||||
.sheet(item: $analyticsLink) { link in
|
||||
AnalyticsView(initialLink: link)
|
||||
.presentationDetents([.large])
|
||||
.presentationDragIndicator(.visible)
|
||||
}
|
||||
#if DEBUG
|
||||
.onAppear {
|
||||
// Test hook: auto-open Quick Add (used to verify the voice→field binding
|
||||
|
||||
@@ -1627,3 +1627,11 @@ last. Device/build QA tracked here.
|
||||
has issues only a compiler will surface. Remaining UI polish: deep-link routing
|
||||
into the presented view, Dynamic-Type audit, denied-permission state for future
|
||||
HealthKit trends.
|
||||
|
||||
### KC-51 progress — Phase 4c: deep-link routing end-to-end (core-verified)
|
||||
- `AnalyticsDeepLink` now `Identifiable` (id = url string) → usable with
|
||||
`.sheet(item:)`. Round-trip re-verified standalone.
|
||||
- Notification tap → stores pending link (delegate) → `ContentView` consumes it on
|
||||
launch + `.active` → presents `AnalyticsView(initialLink:)` opened to the
|
||||
weekly/monthly area. Completes goal condition #7 (report notifications
|
||||
deep-link to their report). Wiring not build-verified (SwiftUI/app deps).
|
||||
|
||||
@@ -13,6 +13,15 @@ struct AnalyticsView: View {
|
||||
@State private var area: Area = .overview
|
||||
@State private var selectedExercise: String?
|
||||
|
||||
/// Optional deep link (from a report notification) picks the initial area.
|
||||
init(initialLink: AnalyticsDeepLink? = nil) {
|
||||
switch initialLink {
|
||||
case .weekly: _area = State(initialValue: .weekly)
|
||||
case .monthly: _area = State(initialValue: .monthly)
|
||||
default: break // keep default .overview
|
||||
}
|
||||
}
|
||||
|
||||
enum Area: String, CaseIterable, Identifiable {
|
||||
case overview = "Overview", daily = "Daily", weekly = "Weekly"
|
||||
case monthly = "Monthly", trends = "12-Month", exercises = "Exercises"
|
||||
|
||||
Reference in New Issue
Block a user