1→// 2→// PlannerTask.swift 3→// Planner2026-iOS 4→// 5→// Core task model with location and AI metadata 6→// 7→ 8→import Foundation 9→import SwiftUI 10→ 11→// MARK: - Enums 12→ 13→enum TaskPriority: String, Codable, CaseIterable { 14→ case low = "Low" 15→ case medium = "Medium" 16→ case high = "High" 17→ case urgent = "Urgent" 18→ 19→ var sortOrder: Int { 20→ switch self { 21→ case .urgent: return 0 22→ case .high: return 1 23→ case .medium: return 2 24→ case .low: return 3 25→ } 26→ } 27→ 28→ var icon: String { 29→ switch self { 30→ case .low: return "arrow.down" 31→ case .medium: return "minus" 32→ case .high: return "arrow.up" 33→ case .urgent: return "exclamationmark.2" 34→ } 35→ } 36→ 37→ var colorHex: String { 38→ switch self { 39→ case .low: return "#8E8E93" 40→ case .medium: return "#007AFF" 41→ case .high: return "#FF9500" 42→ case .urgent: return "#FF3B30" 43→ } 44→ } 45→ 46→ var color: Color { 47→ Color(hex: colorHex) 48→ } 49→} 50→ 51→enum TaskStatus: String, Codable, CaseIterable { 52→ case pending = "Pending" 53→ case inProgress = "In Progress" 54→ case completed = "Completed" 55→ case archived = "Archived" 56→ 57→ var isCompleted: Bool { 58→ self == .completed 59→ } 60→} 61→ 62→// MARK: - PlannerTask 63→ 64→struct PlannerTask: Identifiable, Codable, Hashable { 65→ var id: UUID = UUID() 66→ var title: String 67→ var notes: String = "" 68→ var priority: TaskPriority = .medium 69→ var status: TaskStatus = .pending 70→ var dueDate: Date? 71→ var scheduledDate: Date? // AI-scheduled date 72→ var scheduledTime: Date? // AI-scheduled time 73→ var estimatedMinutes: Int? // Estimated duration 74→ var actualMinutes: Int? // Actual time spent 75→ var projectId: UUID? // Parent project 76→ var subtasks: [Subtask] = [] 77→ var tags: [UUID] = [] 78→ 79→ // Location features 80→ var locationId: UUID? // Associated location 81→ var hasGeofenceReminder: Bool = false 82→ var geofenceRadius: Double = 100 // meters 83→ var triggerOnEntry: Bool = true // vs on exit 84→ 85→ // AI metadata 86→ var isAISuggested: Bool = false 87→ var aiConfidenceScore: Double? // 0-1 88→ var patternNotes: String? // AI pattern insights 89→ 90→ // Timestamps 91→ var createdAt: Date = Date() 92→ var completedAt: Date? 93→ var modifiedAt: Date = Date() 94→ 95→ // MARK: - Computed Properties 96→ 97→ var progress: Double { 98→ guard !subtasks.isEmpty else { return status == .completed ? 1.0 : 0.0 } 99→ return Double(subtasks.filter { $0.isCompleted }.count) / Double(subtasks.count) 100→ } 101→ 102→ var isOverdue: Bool { 103→ guard let due = dueDate, status != .completed else { return false } 104→ return due < Date() 105→ } 106→ 107→ var isDueToday: Bool { 108→ guard let due = dueDate else { return false } 109→ return Calendar.current.isDateInToday(due) 110→ } 111→ 112→ var isDueTomorrow: Bool { 113→ guard let due = dueDate else { return false } 114→ return Calendar.current.isDateInTomorrow(due) 115→ } 116→ 117→ var isDueThisWeek: Bool { 118→ guard let due = dueDate else { return false } 119→ return Calendar.current.isDate(due, equalTo: Date(), toGranularity: .weekOfYear) 120→ } 121→ 122→ var completedSubtasksCount: Int { 123→ subtasks.filter { $0.isCompleted }.count 124→ } 125→ 126→ var hasSubtasks: Bool { 127→ !subtasks.isEmpty 128→ } 129→ 130→ var estimatedDuration: String? { 131→ guard let minutes = estimatedMinutes else { return nil } 132→ if minutes < 60 { 133→ return "\(minutes)m" 134→ } else { 135→ let hours = minutes / 60 136→ let remainingMinutes = minutes % 60 137→ if remainingMinutes == 0 { 138→ return "\(hours)h" 139→ } 140→ return "\(hours)h \(remainingMinutes)m" 141→ } 142→ } 143→} 144→ 145→// MARK: - Subtask 146→ 147→struct Subtask: Identifiable, Codable, Hashable { 148→ var id: UUID = UUID() 149→ var title: String 150→ var isCompleted: Bool = false 151→ var createdAt: Date = Date() 152→ var completedAt: Date? 153→} 154→ 155→// MARK: - Preview Support 156→ 157→#if DEBUG 158→extension PlannerTask { 159→ static var preview: PlannerTask { 160→ PlannerTask( 161→ title: "Complete project proposal", 162→ notes: "Include budget estimates and timeline", 163→ priority: .high, 164→ dueDate: Calendar.current.date(byAdding: .day, value: 2, to: Date()), 165→ estimatedMinutes: 120, 166→ subtasks: [ 167→ Subtask(title: "Research competitors", isCompleted: true), 168→ Subtask(title: "Draft outline", isCompleted: true), 169→ Subtask(title: "Write executive summary", isCompleted: false), 170→ Subtask(title: "Review with team", isCompleted: false) 171→ ] 172→ ) 173→ } 174→ 175→ static var samples: [PlannerTask] { 176→ [ 177→ PlannerTask( 178→ title: "Morning workout", 179→ priority: .medium, 180→ status: .completed, 181→ dueDate: Date(), 182→ estimatedMinutes: 45, 183→ completedAt: Date() 184→ ), 185→ PlannerTask( 186→ title: "Call dentist", 187→ priority: .low, 188→ dueDate: Calendar.current.date(byAdding: .day, value: 1, to: Date()), 189→ hasGeofenceReminder: true, 190→ triggerOnEntry: false 191→ ), 192→ PlannerTask( 193→ title: "Prepare presentation", 194→ priority: .urgent, 195→ dueDate: Date(), 196→ estimatedMinutes: 180 197→ ) 198→ ] 199→ } 200→} 201→#endif 202→ Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.