import Foundation struct DashboardSectionConfig: Identifiable, Codable, Hashable { let id: String var isVisible: Bool var isCollapsed: Bool } enum DashboardSection: String, CaseIterable, Identifiable { case totalValue case monthlyCheckIn case momentumStreaks case monthlySummary case evolution case categoryBreakdown case goals case pendingUpdates case periodReturns var id: String { rawValue } var title: String { switch self { case .totalValue: return "Total Portfolio Value" case .monthlyCheckIn: return "Monthly Check-in" case .momentumStreaks: return "Momentum & Streaks" case .monthlySummary: return "Cashflow vs Growth" case .evolution: return "Portfolio Evolution" case .categoryBreakdown: return "By Category" case .goals: return "Goals" case .pendingUpdates: return "Pending Updates" case .periodReturns: return "Returns" } } } enum DashboardLayoutStore { private static let storageKey = "dashboardLayoutConfig" static func load() -> [DashboardSectionConfig] { let defaults = defaultConfigs() guard let data = UserDefaults.standard.data(forKey: storageKey), let decoded = try? JSONDecoder().decode([DashboardSectionConfig].self, from: data) else { return defaults } var merged: [DashboardSectionConfig] = [] for config in decoded { if let section = DashboardSection(rawValue: config.id) { merged.append(config) } else { continue } } for section in DashboardSection.allCases { if !merged.contains(where: { $0.id == section.id }) { merged.append(defaults.first(where: { $0.id == section.id }) ?? DashboardSectionConfig( id: section.id, isVisible: true, isCollapsed: false )) } } return merged } static func save(_ configs: [DashboardSectionConfig]) { guard let data = try? JSONEncoder().encode(configs) else { return } UserDefaults.standard.set(data, forKey: storageKey) } static func reset() { UserDefaults.standard.removeObject(forKey: storageKey) } private static func defaultConfigs() -> [DashboardSectionConfig] { DashboardSection.allCases.map { section in DashboardSectionConfig( id: section.id, isVisible: true, isCollapsed: false ) } } }