// // OnboardingStyle.swift // Feels // // Created by Claude Code on 12/10/24. // import SwiftUI struct OnboardingStyle: View { @ObservedObject var onboardingData: OnboardingData @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default @AppStorage(UserDefaultsStore.Keys.moodImages.rawValue, store: GroupUserDefaults.groupDefaults) private var imagePack: MoodImages = .FontAwesome var body: some View { ZStack { // Gradient background LinearGradient( colors: [Color(hex: "fa709a"), Color(hex: "fee140")], startPoint: .topLeading, endPoint: .bottomTrailing ) .ignoresSafeArea() ScrollView(showsIndicators: false) { VStack(spacing: 0) { // Icon ZStack { Circle() .fill(.white.opacity(0.15)) .frame(width: 100, height: 100) Image(systemName: "paintpalette.fill") .font(.system(size: 40)) .foregroundColor(.white) } .padding(.top, 40) .padding(.bottom, 20) // Title Text("Make it yours") .font(.system(size: 28, weight: .bold, design: .rounded)) .foregroundColor(.white) .padding(.bottom, 8) // Subtitle Text("Choose your favorite style") .font(.system(size: 16, weight: .medium)) .foregroundColor(.white.opacity(0.85)) .padding(.bottom, 20) // Preview card OnboardingStylePreview(moodTint: moodTint, imagePack: imagePack) .padding(.horizontal, 24) .padding(.bottom, 20) // Icon Style Section VStack(alignment: .leading, spacing: 10) { Text("Icon Style") .font(.system(size: 14, weight: .semibold)) .foregroundColor(.white.opacity(0.9)) .padding(.horizontal, 24) LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 10) { ForEach(MoodImages.allCases, id: \.rawValue) { pack in OnboardingIconPackOption( pack: pack, moodTint: moodTint, isSelected: imagePack == pack, action: { let impactMed = UIImpactFeedbackGenerator(style: .medium) impactMed.impactOccurred() imagePack = pack } ) } } .padding(.horizontal, 24) } .padding(.bottom, 16) // Color Theme Section VStack(alignment: .leading, spacing: 10) { Text("Mood Colors") .font(.system(size: 14, weight: .semibold)) .foregroundColor(.white.opacity(0.9)) .padding(.horizontal, 24) LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 10) { ForEach(MoodTints.defaultOptions, id: \.rawValue) { tint in OnboardingTintOption( tint: tint, isSelected: moodTint == tint, action: { let impactMed = UIImpactFeedbackGenerator(style: .medium) impactMed.impactOccurred() moodTint = tint } ) } } .padding(.horizontal, 24) } // Hint HStack(spacing: 8) { Image(systemName: "arrow.left.arrow.right") .font(.system(size: 14)) Text("You can change these anytime in Customize") .font(.system(size: 13, weight: .medium)) } .foregroundColor(.white.opacity(0.7)) .padding(.top, 20) .padding(.bottom, 80) } } } } } // MARK: - Preview Card struct OnboardingStylePreview: View { let moodTint: MoodTints let imagePack: MoodImages var body: some View { HStack(spacing: 16) { imagePack.icon(forMood: .good) .resizable() .aspectRatio(contentMode: .fit) .frame(width: 44, height: 44) .foregroundColor(moodTint.color(forMood: .good)) VStack(alignment: .leading, spacing: 4) { Text("Wednesday - 10th") .font(.system(size: 17, weight: .semibold)) .foregroundColor(.white) Text(Mood.good.strValue) .font(.system(size: 14)) .foregroundColor(.white.opacity(0.8)) } Spacer() } .padding(20) .background( RoundedRectangle(cornerRadius: 16) .fill(.white.opacity(0.2)) ) } } // MARK: - Icon Pack Option struct OnboardingIconPackOption: View { let pack: MoodImages let moodTint: MoodTints let isSelected: Bool let action: () -> Void var body: some View { Button(action: action) { HStack(spacing: 6) { ForEach([Mood.great, .good, .average], id: \.self) { mood in pack.icon(forMood: mood) .resizable() .aspectRatio(contentMode: .fit) .frame(width: 24, height: 24) .foregroundColor(moodTint.color(forMood: mood)) } } .padding(.horizontal, 16) .padding(.vertical, 14) .background( RoundedRectangle(cornerRadius: 14) .fill(isSelected ? .white : .white.opacity(0.2)) ) .overlay( RoundedRectangle(cornerRadius: 14) .stroke(isSelected ? Color.clear : .white.opacity(0.3), lineWidth: 1) ) } .buttonStyle(.plain) } } // MARK: - Tint Option struct OnboardingTintOption: View { let tint: MoodTints let isSelected: Bool let action: () -> Void var body: some View { Button(action: action) { HStack(spacing: 4) { ForEach([Mood.great, .good, .average, .bad, .horrible], id: \.self) { mood in Circle() .fill(tint.color(forMood: mood)) .frame(width: 20, height: 20) } } .padding(.horizontal, 14) .padding(.vertical, 12) .background( RoundedRectangle(cornerRadius: 14) .fill(isSelected ? .white : .white.opacity(0.2)) ) .overlay( RoundedRectangle(cornerRadius: 14) .stroke(isSelected ? Color.clear : .white.opacity(0.3), lineWidth: 1) ) } .buttonStyle(.plain) } } struct OnboardingStyle_Previews: PreviewProvider { static var previews: some View { OnboardingStyle(onboardingData: OnboardingData()) } }