// // LongestStreakVariations.swift // Reflect // // 2 design variations for the Longest Streak sharing template. // import SwiftUI // MARK: - V2 "Gradient Bar" — Warm gradient bg, horizontal progress struct LongestStreakV2: View { let streakEntries: [MoodEntryModel] let selectedMood: Mood @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default private let dateFormatter: DateFormatter = { let f = DateFormatter() f.dateFormat = "MMM d, yyyy" return f }() var image: UIImage { shareView.asImage(size: CGSize(width: 650, height: 400)) } var shareView: some View { ZStack { LinearGradient( colors: [Color(hex: "FFF5EE"), Color(hex: "FFE4D6")], startPoint: .topLeading, endPoint: .bottomTrailing ) VStack(spacing: 20) { // Top row HStack { VStack(alignment: .leading, spacing: 4) { Text("Longest Streak") .font(.system(size: 14, weight: .semibold, design: .rounded)) .foregroundColor(Color(hex: "8B5E3C")) .textCase(.uppercase) .tracking(2) HStack(alignment: .firstTextBaseline, spacing: 8) { Text("\(streakEntries.count)") .font(.system(size: 56, weight: .heavy, design: .rounded)) .foregroundColor(Color(hex: "4A2810")) Text("days") .font(.system(size: 20, weight: .medium, design: .rounded)) .foregroundColor(Color(hex: "8B5E3C")) } } Spacer() ZStack { Circle() .fill(moodTint.color(forMood: selectedMood)) .frame(width: 72, height: 72) .shadow(color: moodTint.color(forMood: selectedMood).opacity(0.4), radius: 12) selectedMood.icon .resizable() .aspectRatio(contentMode: .fit) .frame(width: 32, height: 32) .foregroundColor(.white) } } .padding(.horizontal, 36) // Progress bar VStack(spacing: 8) { GeometryReader { geo in ZStack(alignment: .leading) { Capsule() .fill(Color(hex: "4A2810").opacity(0.1)) .frame(height: 24) Capsule() .fill(moodTint.color(forMood: selectedMood)) .frame(width: geo.size.width * 0.85, height: 24) .shadow(color: moodTint.color(forMood: selectedMood).opacity(0.3), radius: 6) } } .frame(height: 24) HStack { Text(dateFormatter.string(from: streakEntries.first?.forDate ?? Date())) .font(.system(size: 12, weight: .medium, design: .rounded)) .foregroundColor(Color(hex: "8B5E3C").opacity(0.6)) Spacer() Text(dateFormatter.string(from: streakEntries.last?.forDate ?? Date())) .font(.system(size: 12, weight: .medium, design: .rounded)) .foregroundColor(Color(hex: "8B5E3C").opacity(0.6)) } } .padding(.horizontal, 36) // Footer HStack { Text(selectedMood.strValue) .font(.system(size: 14, weight: .semibold, design: .rounded)) .foregroundColor(Color(hex: "8B5E3C")) Spacer() VStack(spacing: 6) { Image("ReflectAppIcon") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 72, height: 72) .clipShape(RoundedRectangle(cornerRadius: 16)) Text("Reflect") .font(.system(size: 22, weight: .medium, design: .rounded)) .foregroundColor(Color(hex: "8B5E3C").opacity(0.4)) } } .padding(.horizontal, 36) } .padding(.vertical, 32) } .frame(width: 650, height: 400) } var body: some View { shareView } } // MARK: - V3 "Dark Badge" — Dark bg, glowing badge, neon accent struct LongestStreakV3: View { let streakEntries: [MoodEntryModel] let selectedMood: Mood @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default private let dateFormatter: DateFormatter = { let f = DateFormatter() f.dateStyle = .medium return f }() var image: UIImage { shareView.asImage(size: CGSize(width: 650, height: 400)) } var shareView: some View { ZStack { Color(hex: "0A0A0F") HStack(spacing: 0) { // Left half — badge centered ZStack { Circle() .fill(moodTint.color(forMood: selectedMood).opacity(0.15)) .frame(width: 220, height: 220) Circle() .stroke(moodTint.color(forMood: selectedMood).opacity(0.3), lineWidth: 2) .frame(width: 180, height: 180) Circle() .stroke(moodTint.color(forMood: selectedMood), lineWidth: 3) .frame(width: 150, height: 150) VStack(spacing: 4) { Text("\(streakEntries.count)") .font(.system(size: 60, weight: .heavy, design: .rounded)) .foregroundColor(.white) Text("DAYS") .font(.system(size: 13, weight: .bold)) .foregroundColor(moodTint.color(forMood: selectedMood)) .tracking(4) } } .frame(maxWidth: .infinity, maxHeight: .infinity) // Right half — text left-aligned, vertically centered VStack(alignment: .leading, spacing: 20) { Text("LONGEST STREAK") .font(.system(size: 14, weight: .bold)) .foregroundColor(Color(hex: "6E6E80")) .tracking(4) HStack(spacing: 10) { selectedMood.icon .resizable() .aspectRatio(contentMode: .fit) .frame(width: 28, height: 28) .foregroundColor(moodTint.color(forMood: selectedMood)) Text(selectedMood.strValue) .font(.system(size: 30, weight: .semibold)) .foregroundColor(.white) } VStack(alignment: .leading, spacing: 6) { Text(dateFormatter.string(from: streakEntries.first?.forDate ?? Date())) .font(.system(size: 18, weight: .medium)) .foregroundColor(.white.opacity(0.7)) Text("→") .font(.system(size: 16)) .foregroundColor(Color(hex: "6E6E80")) Text(dateFormatter.string(from: streakEntries.last?.forDate ?? Date())) .font(.system(size: 18, weight: .medium)) .foregroundColor(.white.opacity(0.7)) } VStack(spacing: 6) { Image("ReflectAppIcon") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 72, height: 72) .clipShape(RoundedRectangle(cornerRadius: 16)) Text("Reflect") .font(.system(size: 22, weight: .medium)) .foregroundColor(Color(hex: "3A3A4A")) } } .frame(maxWidth: .infinity, maxHeight: .infinity) .padding(.leading, 20) } } .frame(width: 650, height: 400) } var body: some View { shareView } }