This repository has been archived on 2025-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
ios_app/Shared/Views/tab/profile/ProfileTab.swift
2025-07-12 19:50:02 +03:00

298 lines
14 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 = "По дате"
@State private var selectedCategory = "#все"
@State private var searchQuery = ""
@State private var searchQueryArchive = ""
@State private var searchQuerySaved = ""
@State private var searchQueryLiked = ""
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", "Подписки")
}
// Вкладки профиля
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)
if selectedTabIndex == 0 {
HStack {
Menu {
// Здесь список категорий
Button("#все") { selectedCategory = "#все" }
Button("#влог") { selectedCategory = "#влог" }
Button("#игры") { selectedCategory = "#игры" }
Button("#путешествия") { selectedCategory = "#путешествия" }
} label: {
Label(selectedCategory, systemImage: "tag")
.font(.subheadline)
.padding(8)
.background(Color.gray.opacity(0.2))
.cornerRadius(8)
}
// Поиск
TextField("Поиск", text: $searchQuery)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(Color.gray.opacity(0.15))
.cornerRadius(8)
.font(.subheadline)
Button(action: {
// Создание поста
}) {
Label("Создать", systemImage: "plus")
.font(.subheadline)
.padding(8)
.background(Color.blue.opacity(0.2))
.cornerRadius(8)
}
}
.padding(.horizontal)
} else if selectedTabIndex == 1 {
HStack {
// Поиск
TextField("Поиск", text: $searchQueryArchive)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(Color.gray.opacity(0.15))
.cornerRadius(8)
.font(.subheadline)
}
.padding(.horizontal)
} else if selectedTabIndex == 2 {
HStack {
// Поиск
TextField("Поиск", text: $searchQuerySaved)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(Color.gray.opacity(0.15))
.cornerRadius(8)
.font(.subheadline)
}
.padding(.horizontal)
} else if selectedTabIndex == 3 {
HStack {
// Поиск
TextField("Поиск", text: $searchQueryLiked)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(Color.gray.opacity(0.15))
.cornerRadius(8)
.font(.subheadline)
}
.padding(.horizontal)
}
// Контентная часть
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(
ZStack {
// Верхний левый угол дата
VStack {
HStack {
Text("3 года назад")
.font(.caption2)
.foregroundColor(.white)
.padding(4)
.background(Color.black.opacity(0.6))
.cornerRadius(4)
Spacer()
}
Spacer()
}
.padding(4)
// Нижний левый угол просмотры
VStack {
Spacer()
HStack {
HStack(spacing: 4) {
Image(systemName: "play.fill")
.font(.caption2)
Text("1.2k")
.font(.caption2)
}
.foregroundColor(.white)
.padding(4)
.background(Color.black.opacity(0.6))
.cornerRadius(4)
Spacer()
}
.padding(4)
}
}
)
}
}
}
}
.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: .navigationBarLeading) {
Button(action: {
// действие редактирования профиля
}) {
Image(systemName: "paintbrush")
.imageScale(.large)
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
// перейти к настройкам
}) {
Image(systemName: "wrench")
.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)
}
}
}