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)
|
||
}
|
||
}
|
||
}
|