// // MonthTotalVariations.swift // Reflect // // 3 design variations for the Month Total sharing template. // import SwiftUI // MARK: - V1 "Clean Calendar" — Calendar-style grid, Health-app feel struct MonthTotalV1: View { let moodMetrics: [MoodMetrics] let moodEntries: [MoodEntryModel] let month: Int @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default let columns = Array(repeating: GridItem(.flexible(), spacing: 8), count: 7) var image: UIImage { shareView.asImage(size: CGSize(width: 666, height: 1190)) } var shareView: some View { ZStack { Color.white VStack(spacing: 0) { Spacer().frame(height: 70) // Header VStack(spacing: 8) { Text(Random.monthName(fromMonthInt: month)) .font(.system(size: 36, weight: .bold, design: .rounded)) .foregroundColor(Color(hex: "1C1C1E")) Text("\(moodEntries.count) DAYS TRACKED") .font(.system(size: 14, weight: .medium, design: .rounded)) .foregroundColor(Color(hex: "8E8E93")) .tracking(2) } Spacer().frame(height: 40) // Calendar grid LazyVGrid(columns: columns, spacing: 8) { ForEach(moodEntries) { entry in RoundedRectangle(cornerRadius: 10) .fill(moodTint.color(forMood: entry.mood)) .frame(height: 70) .overlay( VStack(spacing: 4) { entry.mood.icon .resizable() .aspectRatio(contentMode: .fit) .frame(width: 20, height: 20) .foregroundColor(.white) Text(DateFormattingCache.shared.string(for: entry.forDate ?? Date(), format: .day)) .font(.system(size: 12, weight: .semibold, design: .rounded)) .foregroundColor(.white.opacity(0.8)) } ) } } .padding(.horizontal, 32) Spacer().frame(height: 40) // Stats row HStack(spacing: 0) { ForEach(moodMetrics.sorted(by: { $0.mood.rawValue > $1.mood.rawValue }), id: \.mood) { metric in VStack(spacing: 8) { Capsule() .fill(moodTint.color(forMood: metric.mood)) .frame(width: 40, height: 6) Text("\(metric.percent, specifier: "%.0f")%") .font(.system(size: 18, weight: .bold, design: .rounded)) .foregroundColor(Color(hex: "1C1C1E")) Text(metric.mood.strValue) .font(.system(size: 11, weight: .medium)) .foregroundColor(Color(hex: "8E8E93")) } .frame(maxWidth: .infinity) } } .padding(.horizontal, 24) Spacer() VStack(spacing: 10) { Image("ReflectAppIcon") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 96, height: 96) .clipShape(RoundedRectangle(cornerRadius: 22)) Text("Reflect") .font(.system(size: 28, weight: .medium, design: .rounded)) .foregroundColor(Color(hex: "C7C7CC")) } Spacer().frame(height: 50) } } .frame(width: 666, height: 1190) } var body: some View { shareView } } // MARK: - V5 "Stacked Bars" — Full-width mood color bars, white overlays struct MonthTotalV5: View { let moodMetrics: [MoodMetrics] let moodEntries: [MoodEntryModel] let month: Int @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default let columns = Array(repeating: GridItem(.flexible(), spacing: 3), count: 7) var image: UIImage { shareView.asImage(size: CGSize(width: 666, height: 1190)) } var shareView: some View { let sorted = moodMetrics.sorted(by: { $0.mood.rawValue > $1.mood.rawValue }) return VStack(spacing: 0) { // Header — dark band ZStack { Color(hex: "1C1C1E") HStack { Text(Random.monthName(fromMonthInt: month).uppercased()) .font(.system(size: 18, weight: .heavy, design: .rounded)) .foregroundColor(.white) .tracking(4) Spacer() Text("\(moodEntries.count)") .font(.system(size: 28, weight: .heavy, design: .rounded)) .foregroundColor(.white) } .padding(.horizontal, 32) } .frame(height: 80) // Mini grid of all days ZStack { Color(hex: "1C1C1E") LazyVGrid(columns: columns, spacing: 3) { ForEach(moodEntries) { entry in Rectangle() .fill(moodTint.color(forMood: entry.mood)) .frame(height: 50) } } .padding(24) } // Color percentage blocks ForEach(sorted, id: \.mood) { metric in let barHeight: CGFloat = max(CGFloat(metric.percent / 100) * 400, 50) ZStack { moodTint.color(forMood: metric.mood) HStack { VStack(alignment: .leading, spacing: 2) { Text(metric.mood.strValue.uppercased()) .font(.system(size: 13, weight: .bold, design: .rounded)) .tracking(2) Text("\(metric.total) days") .font(.system(size: 11, weight: .medium)) .opacity(0.7) } Spacer() Text("\(metric.percent, specifier: "%.0f")%") .font(.system(size: 32, weight: .heavy, design: .rounded)) } .foregroundColor(.white) .padding(.horizontal, 32) } .frame(height: barHeight) } // Footer — dark band fills remaining space ZStack { Color(hex: "1C1C1E") VStack(spacing: 10) { Image("ReflectAppIcon") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 96, height: 96) .clipShape(RoundedRectangle(cornerRadius: 22)) Text("Reflect") .font(.system(size: 28, weight: .bold, design: .rounded)) .foregroundColor(.white.opacity(0.3)) } } .frame(maxHeight: .infinity) } .background(Color(hex: "1C1C1E")) .frame(width: 666, height: 1190) } var body: some View { shareView } }