197 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
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)
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 |