import SwiftUI struct ProfileTab: View { @ObservedObject var viewModel: LoginViewModel @State private var showingAccountSwitch = false @State private var selectedTabIndex = 0 @State private var selectedSort = "По дате" var body: some View { NavigationView { GeometryReader { geometry in VStack(spacing: 0) { ScrollView { VStack(spacing: 12) { // Аватар и имя VStack(spacing: 6) { Image(systemName: "person.crop.circle.fill") .resizable() .frame(width: 72, height: 72) .foregroundColor(.gray) Text("@username") .font(.headline) } .padding(.top, 16) // Статистика HStack(spacing: 32) { statView("24", "Посты") statView("1.2k", "Подписчики") statView("156", "Подписки") } // Кнопка редактирования Button(action: { // редактировать профиль }) { Text("Редактировать профиль") .font(.subheadline) .padding(.horizontal, 24) .padding(.vertical, 8) .overlay( RoundedRectangle(cornerRadius: 8) .stroke(Color.gray, lineWidth: 1) ) } .padding(.top, 8) // Вкладки профиля HStack(spacing: 32) { menuTab(index: 0) tabButton(index: 1, systemIcon: "lock") tabButton(index: 2, systemIcon: "bookmark") tabButton(index: 3, systemIcon: "heart") } .padding(.vertical, 12) } .padding(.horizontal) .frame(width: geometry.size.width) // Контентная часть TabView(selection: $selectedTabIndex) { ForEach(0..<4) { index in LazyVGrid(columns: Array(repeating: .init(.flexible()), count: 3), spacing: 2) { ForEach(0..<36) { _ in Rectangle() .fill(contentColor(for: index)) .aspectRatio(1, contentMode: .fit) .overlay( index == 0 ? Text(selectedSort) .font(.caption2) .foregroundColor(.gray) .padding(4) : nil, alignment: .bottomTrailing ) } } .padding(.horizontal) .tag(index) } } .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) // .frame(height: geometry.size.width * 1.2) // Динамическая высота } } } .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .principal) { Button(action: { showingAccountSwitch.toggle() }) { HStack(spacing: 4) { Text("custom_user_name") .font(.headline) .foregroundColor(.primary) Image(systemName: "chevron.down") .font(.subheadline) .foregroundColor(.gray) } } } ToolbarItem(placement: .navigationBarTrailing) { Button(action: { // перейти к настройкам }) { Image(systemName: "gearshape") .imageScale(.large) } } } .sheet(isPresented: $showingAccountSwitch) { VStack { Text("Выбор аккаунта") .font(.title) .padding() Button("Закрыть") { showingAccountSwitch = false } .padding() } } } } // MARK: - Статистика func statView(_ value: String, _ label: String) -> some View { VStack { Text(value) .font(.headline) Text(label) .font(.caption) } } // MARK: - Вкладка с меню @ViewBuilder func menuTab(index: Int) -> some View { Menu { if selectedTabIndex == index { Button("По дате") { selectedSort = "По дате" } Button("По популярности") { selectedSort = "По популярности" } } } label: { VStack(spacing: 4) { HStack(spacing: 4) { Image(systemName: "rectangle.grid.3x2") .font(.system(size: 18, weight: .medium)) .foregroundColor(.primary) // Показываем стрелку вниз только если вкладка активна if selectedTabIndex == index { Image(systemName: "chevron.down") .font(.system(size: 10)) .foregroundColor(.gray) } } Rectangle() .frame(height: 2) .foregroundColor(selectedTabIndex == index ? .primary : .clear) } .frame(maxWidth: .infinity) } .onTapGesture { selectedTabIndex = index } } // MARK: - Остальные вкладки @ViewBuilder func tabButton(index: Int, systemIcon: String) -> some View { VStack(spacing: 4) { Image(systemName: systemIcon) .font(.system(size: 18, weight: .medium)) .foregroundColor(selectedTabIndex == index ? .primary : .gray) Rectangle() .frame(height: 2) .foregroundColor(selectedTabIndex == index ? .primary : .clear) } .frame(maxWidth: .infinity) .onTapGesture { selectedTabIndex = index } } // MARK: - Цвет контента func contentColor(for tab: Int) -> Color { switch tab { case 0: return Color.gray.opacity(0.3) case 1: return Color.blue.opacity(0.3) case 2: return Color.green.opacity(0.3) case 3: return Color.red.opacity(0.3) default: return Color.gray.opacity(0.3) } } }