Files
KisaniCal/KisaniCal/Analytics/AnalyticsDeepLink.swift
kutesir bcbcda5ba5 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>
2026-07-12 22:57:13 +00:00

59 lines
1.9 KiB
Swift

import Foundation
/// Deep links into the Analytics area used by weekly/monthly report
/// notifications to route straight to the relevant report. Pure value type with
/// symmetric URL encode/decode so routing is testable without any UI.
///
/// Format: wenza://analytics overview
/// wenza://analytics/weekly/<yyyy-MM-dd> a weekly report
/// wenza://analytics/monthly/<yyyy-MM> a monthly report
enum AnalyticsDeepLink: Equatable, Identifiable {
case overview
case weekly(weekStartKey: String)
case monthly(monthKey: String)
static let scheme = "wenza"
static let host = "analytics"
var id: String { stringValue }
/// Stable userInfo key carried on notifications.
static let userInfoKey = "kisani.analytics.deeplink"
var url: URL {
var c = URLComponents()
c.scheme = Self.scheme
c.host = Self.host
switch self {
case .overview: c.path = ""
case .weekly(let key): c.path = "/weekly/\(key)"
case .monthly(let key): c.path = "/monthly/\(key)"
}
return c.url!
}
init?(url: URL) {
guard url.scheme == Self.scheme, url.host == Self.host else { return nil }
let parts = url.path.split(separator: "/").map(String.init)
switch parts.first {
case nil:
self = .overview
case "weekly":
guard parts.count >= 2 else { return nil }
self = .weekly(weekStartKey: parts[1])
case "monthly":
guard parts.count >= 2 else { return nil }
self = .monthly(monthKey: parts[1])
default:
return nil
}
}
/// Build/parse via a plain string (for notification userInfo payloads).
var stringValue: String { url.absoluteString }
init?(string: String) {
guard let url = URL(string: string) else { return nil }
self.init(url: url)
}
}