Files
Reflect/Shared/Onboarding/views/OnboardingDay.swift
Trey t 0442eab1f8 Rebrand entire project from Feels to Reflect
Complete rename across all bundle IDs, App Groups, CloudKit containers,
StoreKit product IDs, data store filenames, URL schemes, logger subsystems,
Swift identifiers, user-facing strings (7 languages), file names, directory
names, Xcode project, schemes, assets, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 11:47:16 -06:00

188 lines
6.2 KiB
Swift

//
// OnboardingDay.swift
// Reflect (iOS)
//
// Created by Trey Tartt on 1/20/22.
//
import SwiftUI
enum DayOptions: Int, CaseIterable, RawRepresentable, Codable {
case Today
case Previous
var localizedValue: String {
switch self {
case .Today:
return String(localized: "onboarding_day_options_today")
case .Previous:
return String(localized: "onboarding_day_options_yesterday")
}
}
}
struct OnboardingDay: View {
@ObservedObject var onboardingData: OnboardingData
var body: some View {
VStack(spacing: 0) {
Spacer()
// Icon
ZStack {
Circle()
.fill(.white.opacity(0.15))
.frame(width: 120, height: 120)
Image(systemName: "calendar")
.font(.largeTitle)
.foregroundColor(.white)
}
.padding(.bottom, 32)
// Title
Text("Which day should\nyou rate?")
.font(.title.weight(.bold))
.foregroundColor(.white)
.multilineTextAlignment(.center)
.padding(.bottom, 12)
// Subtitle
Text("When you get your reminder, do you want to rate today or yesterday?")
.font(.body.weight(.medium))
.foregroundColor(.white.opacity(0.85))
.multilineTextAlignment(.center)
.padding(.horizontal, 40)
Spacer()
// Options
VStack(spacing: 14) {
DayOptionCard(
title: "Today",
subtitle: "Rate the current day",
example: "e.g. Tue reminder → Rate Tue",
icon: "sun.max.fill",
isSelected: onboardingData.inputDay == .Today,
action: { onboardingData.inputDay = .Today },
testID: AccessibilityID.Onboarding.dayToday
)
DayOptionCard(
title: "Yesterday",
subtitle: "Rate the previous day",
example: "e.g. Tue reminder → Rate Mon",
icon: "moon.fill",
isSelected: onboardingData.inputDay == .Previous,
action: { onboardingData.inputDay = .Previous },
testID: AccessibilityID.Onboarding.dayYesterday
)
}
.padding(.horizontal, 20)
Spacer()
// Tip
HStack(spacing: 12) {
Image(systemName: "lightbulb.fill")
.font(.headline)
.foregroundColor(.yellow)
Text("Tip: \"Today\" works great for evening reminders")
.font(.subheadline.weight(.medium))
.foregroundColor(.white.opacity(0.9))
}
.padding(.horizontal, 30)
.padding(.bottom, 80)
}
.background(
LinearGradient(
colors: [Color(hex: "4facfe"), Color(hex: "00f2fe")],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
.ignoresSafeArea()
)
.accessibilityIdentifier(AccessibilityID.Onboarding.dayScreen)
}
}
struct DayOptionCard: View {
let title: String
let subtitle: String
let example: String
let icon: String
let isSelected: Bool
let action: () -> Void
var testID: String? = nil
var body: some View {
Button(action: action) {
HStack(spacing: 14) {
// Icon
ZStack {
Circle()
.fill(isSelected ? Color.white : Color.white.opacity(0.2))
.frame(width: 46, height: 46)
Image(systemName: icon)
.font(.title3)
.foregroundColor(isSelected ? Color(hex: "4facfe") : .white)
}
.accessibilityHidden(true)
// Text
VStack(alignment: .leading, spacing: 3) {
Text(title)
.font(.body.weight(.semibold))
.foregroundColor(isSelected ? Color(hex: "4facfe") : .white)
Text(subtitle)
.font(.caption)
.foregroundColor(isSelected ? Color(hex: "4facfe").opacity(0.8) : .white.opacity(0.8))
Text(example)
.font(.caption2.weight(.medium))
.foregroundColor(isSelected ? Color(hex: "4facfe").opacity(0.6) : .white.opacity(0.6))
.lineLimit(1)
.minimumScaleFactor(0.8)
}
Spacer(minLength: 8)
// Checkmark
if isSelected {
Image(systemName: "checkmark.circle.fill")
.font(.title3)
.foregroundColor(Color(hex: "4facfe"))
.accessibilityHidden(true)
}
}
.padding(.horizontal, 16)
.padding(.vertical, 18)
.background(
RoundedRectangle(cornerRadius: 18)
.fill(isSelected ? .white : .white.opacity(0.15))
.shadow(color: isSelected ? .black.opacity(0.1) : .clear, radius: 10, y: 5)
)
}
.buttonStyle(.plain)
.accessibilityElement(children: .combine)
.accessibilityLabel("\(title), \(subtitle)")
.accessibilityHint(example)
.accessibilityAddTraits(isSelected ? [.isSelected] : [])
.accessibilityIdentifier(testID ?? "")
}
}
struct OnboardingDay_Previews: PreviewProvider {
static var previews: some View {
Group {
OnboardingDay(onboardingData: OnboardingData())
OnboardingDay(onboardingData: OnboardingData())
.preferredColorScheme(.dark)
}
}
}