ios_app/Shared/Views/tab/profile/ProfileTab.swift
2025-07-12 02:41:46 +03:00

197 lines
8.0 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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