From 7b2b61a22884b47ef8510a8bfa192507bcab9b02 Mon Sep 17 00:00:00 2001 From: kutesir Date: Tue, 9 Jun 2026 00:48:17 +0300 Subject: [PATCH] Calendar: show the year (fix "can't navigate past 2026") Navigation was unbounded, but headers only showed the month name so the year change was invisible and future months felt unreachable. - Main calendar header now shows "Month Year". - Date-picker grid label shows the year. - Year view gets a chevron year navigator (unbounded) + year label. Co-Authored-By: Claude Opus 4.8 --- KisaniCal/Views/CalendarView.swift | 39 ++++++++++++++++++++++++------ KisaniCal/Views/TodayView.swift | 2 +- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/KisaniCal/Views/CalendarView.swift b/KisaniCal/Views/CalendarView.swift index 60ec03e..1df50ff 100644 --- a/KisaniCal/Views/CalendarView.swift +++ b/KisaniCal/Views/CalendarView.swift @@ -326,9 +326,9 @@ struct CalendarView: View { } .menuStyle(.automatic) - // Center: month name + // Center: month + year Spacer() - Text(monthShortTitle) + Text(monthTitle) .font(AppFonts.sans(17, weight: .semibold)) .foregroundColor(AppColors.text(cs)) Spacer() @@ -673,13 +673,38 @@ struct CalendarView: View { private var yearView: some View { let year = cal.component(.year, from: displayMonth) let months: [Date] = (1...12).compactMap { cal.date(from: DateComponents(year: year, month: $0, day: 1)) } - return ScrollView(showsIndicators: false) { - LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())], spacing: 24) { - ForEach(months, id: \.self) { m in - cvMiniMonth(m) + return VStack(spacing: 0) { + // Year header with navigation (unbounded — go as far forward/back as you like). + HStack { + Button { navigateYear(-1) } label: { + Image(systemName: "chevron.left").font(.system(size: 14, weight: .semibold)) + .foregroundColor(AppColors.text(cs)).frame(width: 40, height: 40) + } + Spacer() + Text(String(year)) + .font(AppFonts.sans(20, weight: .bold)).foregroundColor(AppColors.text(cs)) + Spacer() + Button { navigateYear(1) } label: { + Image(systemName: "chevron.right").font(.system(size: 14, weight: .semibold)) + .foregroundColor(AppColors.text(cs)).frame(width: 40, height: 40) } } - .padding(16) + .padding(.horizontal, 16).padding(.top, 4) + + ScrollView(showsIndicators: false) { + LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())], spacing: 24) { + ForEach(months, id: \.self) { m in + cvMiniMonth(m) + } + } + .padding(16) + } + } + } + + private func navigateYear(_ offset: Int) { + withAnimation(KisaniSpring.snappy) { + displayMonth = cal.date(byAdding: .year, value: offset, to: displayMonth) ?? displayMonth } } diff --git a/KisaniCal/Views/TodayView.swift b/KisaniCal/Views/TodayView.swift index d066535..951882d 100644 --- a/KisaniCal/Views/TodayView.swift +++ b/KisaniCal/Views/TodayView.swift @@ -2560,7 +2560,7 @@ struct CalendarGridView: View { } private var monthLabel: String { - let f = DateFormatter(); f.dateFormat = "MMMM"; return f.string(from: displayMonth) + let f = DateFormatter(); f.dateFormat = "MMMM yyyy"; return f.string(from: displayMonth) } private func shift(_ d: Int) {