feat: полноценное Pulse приложение с TabBar

- Auth: переключено на Pulse API (api.digital-home.site) вместо health
- TabBar: Главная, Задачи, Привычки, Здоровье, Финансы
- Models: TaskModels, HabitModels, FinanceModels, обновлённые AuthModels
- Services: APIService (Pulse API), HealthAPIService (health отдельно)
- Dashboard: обзор дня с задачами, привычками, readiness, балансом
- Tasks: список, фильтр, создание, выполнение, удаление
- Habits: список с прогресс-баром, отметка выполнения, стрики
- Health: бывший DashboardView, HealthKit sync через health API key
- Finance: баланс, список транзакций, добавление расхода/дохода
- Health данные через x-api-key вместо JWT токена health сервиса
This commit is contained in:
Cosmo
2026-03-25 11:49:52 +00:00
parent cf0e535639
commit c015824b36
23 changed files with 1090 additions and 202 deletions

View File

@@ -17,14 +17,17 @@ extension Color {
}
@main
struct PulseHealthApp: App {
struct PulseApp: App {
@StateObject private var authManager = AuthManager()
var body: some Scene {
WindowGroup {
if authManager.isLoggedIn {
DashboardView().environmentObject(authManager)
MainTabView()
.environmentObject(authManager)
} else {
LoginView().environmentObject(authManager)
LoginView()
.environmentObject(authManager)
}
}
}
@@ -34,25 +37,32 @@ class AuthManager: ObservableObject {
@Published var isLoggedIn: Bool = false
@Published var token: String = ""
@Published var userName: String = ""
@Published var apiKey: String = ""
@Published var userId: Int = 0
@Published var healthApiKey: String = "health-cosmo-2026"
init() {
token = UserDefaults.standard.string(forKey: "authToken") ?? ""
token = UserDefaults.standard.string(forKey: "pulseToken") ?? ""
userName = UserDefaults.standard.string(forKey: "userName") ?? ""
apiKey = UserDefaults.standard.string(forKey: "apiKey") ?? ""
userId = UserDefaults.standard.integer(forKey: "userId")
healthApiKey = UserDefaults.standard.string(forKey: "healthApiKey") ?? "health-cosmo-2026"
isLoggedIn = !token.isEmpty
}
func login(token: String, name: String, apiKey: String) {
self.token = token; self.userName = name; self.apiKey = apiKey
UserDefaults.standard.set(token, forKey: "authToken")
UserDefaults.standard.set(name, forKey: "userName")
UserDefaults.standard.set(apiKey, forKey: "apiKey")
func login(token: String, user: UserInfo) {
self.token = token
self.userName = user.name ?? user.email
self.userId = user.id
UserDefaults.standard.set(token, forKey: "pulseToken")
UserDefaults.standard.set(user.name ?? user.email, forKey: "userName")
UserDefaults.standard.set(user.id, forKey: "userId")
isLoggedIn = true
}
func logout() {
token = ""; userName = ""; apiKey = ""
UserDefaults.standard.removeObject(forKey: "authToken")
token = ""; userName = ""; userId = 0
UserDefaults.standard.removeObject(forKey: "pulseToken")
UserDefaults.standard.removeObject(forKey: "userName")
UserDefaults.standard.removeObject(forKey: "apiKey")
UserDefaults.standard.removeObject(forKey: "userId")
isLoggedIn = false
}
}