164 lines
6.6 KiB
Swift
164 lines
6.6 KiB
Swift
import SwiftUI
|
||
|
||
struct SettingsView: View {
|
||
@ObservedObject var viewModel: LoginViewModel
|
||
@EnvironmentObject private var themeManager: ThemeManager
|
||
@State private var isThemeExpanded = false
|
||
private let themeOptions = ThemeOption.ordered
|
||
|
||
private var selectedThemeOption: ThemeOption {
|
||
ThemeOption.option(for: themeManager.theme)
|
||
}
|
||
|
||
var body: some View {
|
||
Form {
|
||
// MARK: - Профиль
|
||
Section(header: Text(NSLocalizedString("Профиль", comment: ""))) {
|
||
// NavigationLink(destination: EditProfileView()) {
|
||
// Label("Мой профиль", systemImage: "person.crop.circle")
|
||
// }
|
||
|
||
NavigationLink(destination: EditPrivacyView()) {
|
||
Label(NSLocalizedString("Конфиденциальность", comment: ""), systemImage: "lock.fill")
|
||
}
|
||
}
|
||
|
||
// MARK: - Безопасность
|
||
Section(header: Text(NSLocalizedString("Безопасность", comment: ""))) {
|
||
NavigationLink(destination: ChangePasswordView()) {
|
||
Label(NSLocalizedString("Сменить пароль", comment: ""), systemImage: "key")
|
||
}
|
||
NavigationLink(destination: Text("Заглушка: Двухфакторная аутентификация")) {
|
||
Label("Двухфакторная аутентификация", systemImage: "lock.shield")
|
||
}
|
||
NavigationLink(destination: Text("Заглушка: Активные сессии")) {
|
||
Label("Активные сессии", systemImage: "iphone")
|
||
}
|
||
}
|
||
|
||
// MARK: - Приложение
|
||
Section(header: Text("Приложение")) {
|
||
Button(action: openLanguageSettings) {
|
||
Label("Язык", systemImage: "globe")
|
||
}
|
||
|
||
DisclosureGroup(isExpanded: $isThemeExpanded) {
|
||
VStack(alignment: .leading, spacing: 12) {
|
||
ForEach(Array(themeOptions.enumerated()), id: \.element.id) { index, option in
|
||
themeRow(for: option)
|
||
if index < themeOptions.count - 1 {
|
||
Divider()
|
||
}
|
||
}
|
||
}
|
||
.padding(.vertical, 4)
|
||
} label: {
|
||
Label("Темы", systemImage: "moon.fill")
|
||
}
|
||
|
||
NavigationLink(destination: Text("Заглушка: Хранилище данных")) {
|
||
Label("Данные", systemImage: "externaldrive")
|
||
}
|
||
|
||
NavigationLink(destination: OtherSettingsView()) {
|
||
Label("Другое", systemImage: "ellipsis.circle")
|
||
}
|
||
}
|
||
|
||
// MARK: - Уведомления
|
||
Section(header: Text("Уведомления")) {
|
||
NavigationLink(destination: Text("Заглушка: Push-уведомления")) {
|
||
Label("Push-уведомления", systemImage: "bell")
|
||
}
|
||
}
|
||
|
||
// MARK: - Поддержка
|
||
Section(header: Text("Поддержка")) {
|
||
NavigationLink(destination: FAQView()) {
|
||
Label("Частые вопросы", systemImage: "questionmark.circle")
|
||
}
|
||
NavigationLink(destination: FeedbackView()) {
|
||
Label("Обратная связь", systemImage: "paperplane")
|
||
}
|
||
}
|
||
|
||
// MARK: - О приложении
|
||
// Section(header: Text("О приложении")) {
|
||
// VStack(alignment: .leading, spacing: 6) {
|
||
// Text(AppInfo.text_1)
|
||
// Text(AppInfo.text_2)
|
||
// Text(AppInfo.text_3)
|
||
// }
|
||
// .font(.footnote)
|
||
// .foregroundColor(.gray)
|
||
// .padding(.vertical, 4)
|
||
// }
|
||
|
||
Section(header: Text(NSLocalizedString("О приложении", comment: ""))) {
|
||
VStack(alignment: .leading, spacing: 6) {
|
||
Text(
|
||
"\(NSLocalizedString("Версия:", comment: "")) \(Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "")")
|
||
Text(
|
||
"\(NSLocalizedString("Сборка:", comment: "")) \(Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "")")
|
||
Text("© 2025 Yobble Org. \(NSLocalizedString("Все права защищены.", comment: ""))")
|
||
}
|
||
.font(.footnote)
|
||
.foregroundColor(.gray)
|
||
.padding(.vertical, 4)
|
||
}
|
||
|
||
// MARK: - Выход
|
||
Section {
|
||
Button(action: {
|
||
viewModel.logoutCurrentUser()
|
||
}) {
|
||
HStack {
|
||
Image(systemName: "arrow.backward.square")
|
||
Text("Выйти из аккаунта")
|
||
}
|
||
.foregroundColor(.red)
|
||
}
|
||
}
|
||
}
|
||
.navigationTitle("Настройки")
|
||
}
|
||
|
||
private func openLanguageSettings() {
|
||
guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
|
||
UIApplication.shared.open(url)
|
||
}
|
||
|
||
private func themeRow(for option: ThemeOption) -> some View {
|
||
let isSelected = option == selectedThemeOption
|
||
|
||
return Button(action: {
|
||
selectTheme(option)
|
||
}) {
|
||
HStack(spacing: 12) {
|
||
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
|
||
.foregroundColor(isSelected ? .accentColor : .secondary)
|
||
VStack(alignment: .leading, spacing: 2) {
|
||
Text(option.title)
|
||
.foregroundColor(.primary)
|
||
if let note = option.note {
|
||
Text(note)
|
||
.font(.caption)
|
||
.foregroundColor(.secondary)
|
||
}
|
||
}
|
||
Spacer()
|
||
}
|
||
.contentShape(Rectangle())
|
||
}
|
||
.disabled(!option.isEnabled)
|
||
.opacity(option.isEnabled ? 1.0 : 0.5)
|
||
.buttonStyle(.plain)
|
||
}
|
||
|
||
private func selectTheme(_ option: ThemeOption) {
|
||
guard let mappedTheme = option.mappedTheme else { return }
|
||
themeManager.setTheme(mappedTheme)
|
||
}
|
||
|
||
}
|