// // VotingLayoutPickerView.swift // Feels (iOS) // // Created by Claude Code on 12/9/24. // import SwiftUI struct VotingLayoutPickerView: View { @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system @AppStorage(UserDefaultsStore.Keys.textColor.rawValue, store: GroupUserDefaults.groupDefaults) private var textColor: Color = DefaultTextColor.textColor @AppStorage(UserDefaultsStore.Keys.votingLayoutStyle.rawValue, store: GroupUserDefaults.groupDefaults) private var votingLayoutStyle: Int = 0 private var currentLayout: VotingLayoutStyle { VotingLayoutStyle(rawValue: votingLayoutStyle) ?? .horizontal } var body: some View { ZStack { theme.currentTheme.secondaryBGColor VStack(alignment: .leading, spacing: 12) { Text("Voting Layout") .font(.headline) .foregroundColor(textColor) .padding(.horizontal) .padding(.top) HStack(spacing: 8) { ForEach(VotingLayoutStyle.allCases, id: \.rawValue) { layout in Button(action: { withAnimation(.easeInOut(duration: 0.2)) { votingLayoutStyle = layout.rawValue } EventLogger.log(event: "change_voting_layout", withData: ["layout": layout.displayName]) }) { VStack(spacing: 6) { layoutIcon(for: layout) .frame(width: 44, height: 44) .foregroundColor(currentLayout == layout ? .accentColor : textColor.opacity(0.6)) Text(layout.displayName) .font(.caption) .foregroundColor(currentLayout == layout ? .accentColor : textColor.opacity(0.8)) } .frame(maxWidth: .infinity) .padding(.vertical, 12) .background( RoundedRectangle(cornerRadius: 10) .fill(currentLayout == layout ? Color.accentColor.opacity(0.15) : Color.clear) ) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(currentLayout == layout ? Color.accentColor : Color.clear, lineWidth: 2) ) } .buttonStyle(.plain) } } .padding(.horizontal) .padding(.bottom) } } .fixedSize(horizontal: false, vertical: true) .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) } @ViewBuilder private func layoutIcon(for layout: VotingLayoutStyle) -> some View { switch layout { case .horizontal: HStack(spacing: 4) { ForEach(0..<5) { _ in Circle() .frame(width: 6, height: 6) } } case .cards: LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())], spacing: 3) { ForEach(0..<6) { _ in RoundedRectangle(cornerRadius: 2) .frame(width: 10, height: 12) } } case .radial: ZStack { ForEach(0..<5) { index in Circle() .frame(width: 6, height: 6) .offset(radialOffset(index: index, total: 5, radius: 16)) } } case .stacked: VStack(spacing: 3) { ForEach(0..<4) { _ in RoundedRectangle(cornerRadius: 2) .frame(width: 32, height: 6) } } } } private func radialOffset(index: Int, total: Int, radius: CGFloat) -> CGSize { let angle = Double.pi - (Double.pi * Double(index) / Double(total - 1)) return CGSize( width: radius * CGFloat(cos(angle)), height: -radius * CGFloat(sin(angle)) + 4 ) } } struct VotingLayoutPickerView_Previews: PreviewProvider { static var previews: some View { VotingLayoutPickerView() .padding() } }