import SwiftUI import Bedrock /// Shown when there are active rituals but none scheduled for the current time of day. struct TodayNoRitualsForTimeView: View { @Bindable var store: RitualStore private var currentTimePeriod: TimeOfDay { let hour = Calendar.current.component(.hour, from: Date()) switch hour { case 0..<11: return .morning case 11..<14: return .midday case 14..<17: return .afternoon case 17..<21: return .evening default: return .night } } private var nextRituals: [Ritual] { // Find rituals scheduled for later time periods store.currentRituals.filter { ritual in guard let arc = ritual.currentArc, arc.contains(date: Date()) else { return false } return ritual.timeOfDay != .anytime && ritual.timeOfDay > currentTimePeriod } } private var nextRitualTomorrow: Ritual? { let calendar = Calendar.current let tomorrowDate = calendar.startOfDay( for: calendar.date(byAdding: .day, value: 1, to: Date()) ?? Date() ) return store.currentRituals .filter { ritual in guard let arc = ritual.currentArc, arc.contains(date: tomorrowDate) else { return false } return ritual.timeOfDay != .anytime } .sorted { $0.timeOfDay < $1.timeOfDay } .first } var body: some View { VStack(alignment: .leading, spacing: Design.Spacing.large) { SectionHeaderView( title: String(localized: "All caught up"), subtitle: currentTimePeriod.displayName ) VStack(spacing: Design.Spacing.large) { // Icon Image(systemName: currentTimePeriod.symbolName) .font(.system(size: Design.IconSize.hero)) .foregroundStyle(AppAccent.primary.opacity(0.6)) .padding(.top, Design.Spacing.large) VStack(spacing: Design.Spacing.xSmall) { Text(String(localized: "No rituals scheduled for \(currentTimePeriod.displayName.lowercased()).")) .font(.subheadline) .foregroundStyle(AppTextColors.secondary) .multilineTextAlignment(.center) Text(currentTimePeriod.timeRange) .font(.caption) .foregroundStyle(AppTextColors.tertiary) } // Show upcoming rituals if any if !nextRituals.isEmpty { VStack(alignment: .leading, spacing: Design.Spacing.medium) { Text(String(localized: "Coming up later:")) .font(.caption) .foregroundStyle(AppTextColors.tertiary) ForEach(nextRituals) { ritual in HStack(spacing: Design.Spacing.small) { Image(systemName: ritual.timeOfDay.symbolName) .font(.caption) .foregroundStyle(AppTextColors.secondary) Text(ritual.title) .font(.subheadline) .foregroundStyle(AppTextColors.primary) Spacer() Text(ritual.timeOfDay.displayName) .font(.caption) .foregroundStyle(AppTextColors.tertiary) } .padding(Design.Spacing.small) .background(AppSurface.secondary) .clipShape(.rect(cornerRadius: Design.CornerRadius.small)) } } .padding(.top, Design.Spacing.small) } else if let tomorrowRitual = nextRitualTomorrow { let format = String(localized: "Next ritual: Tomorrow %@ (%@)") Text(String.localizedStringWithFormat( format, tomorrowRitual.timeOfDay.displayName, tomorrowRitual.timeOfDay.timeRange )) .font(.caption) .foregroundStyle(AppTextColors.tertiary) .multilineTextAlignment(.center) .padding(.top, Design.Spacing.small) } // Motivational message Text(String(localized: "Enjoy this moment. Your next ritual will appear when it's time.")) .font(.caption) .foregroundStyle(AppTextColors.tertiary) .multilineTextAlignment(.center) .padding(.top, Design.Spacing.small) } .padding(Design.Spacing.large) .frame(maxWidth: .infinity) .background(AppSurface.card) .clipShape(.rect(cornerRadius: Design.CornerRadius.large)) } } } #Preview { TodayNoRitualsForTimeView(store: RitualStore.preview) .padding() .background(AppSurface.primary) }