78 lines
2.2 KiB
Swift
78 lines
2.2 KiB
Swift
import SwiftUI
|
|
import CoreModel
|
|
import CoreUI
|
|
import DesignSystem
|
|
|
|
public struct HomeScreen: View {
|
|
private let viewModel: HomeViewModel
|
|
|
|
public init(viewModel: HomeViewModel) {
|
|
self.viewModel = viewModel
|
|
}
|
|
|
|
public var body: some View {
|
|
content
|
|
.navigationTitle("首页")
|
|
.task { viewModel.load() }
|
|
}
|
|
|
|
@ViewBuilder
|
|
private var content: some View {
|
|
switch viewModel.uiState {
|
|
case .loading:
|
|
LoadingView()
|
|
case .empty:
|
|
EmptyStateView(title: "今天还没有待打卡的习惯", systemImage: "checkmark.circle")
|
|
case .success(let data):
|
|
successContent(data)
|
|
case .error(let message):
|
|
ErrorView(message: message) { viewModel.load() }
|
|
}
|
|
}
|
|
|
|
private func successContent(_ data: HomeData) -> some View {
|
|
List {
|
|
Section {
|
|
VStack(alignment: .leading, spacing: DS.Spacing.sm) {
|
|
Text(data.greeting)
|
|
.font(.largeTitle.bold())
|
|
Text(data.summary)
|
|
.font(.subheadline)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
.padding(.vertical, DS.Spacing.sm)
|
|
}
|
|
|
|
Section("今日打卡") {
|
|
ForEach(data.habits) { habit in
|
|
HabitRow(habit: habit)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct HabitRow: View {
|
|
let habit: Habit
|
|
|
|
var body: some View {
|
|
HStack {
|
|
Image(systemName: habit.isCheckedInToday ? "checkmark.circle.fill" : "circle")
|
|
.foregroundStyle(habit.isCheckedInToday ? DS.Color.success : DS.Color.warning)
|
|
.font(.title3)
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
Text(habit.title)
|
|
.font(.headline)
|
|
Text(habit.detail)
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
Spacer()
|
|
Text("🔥 \(habit.streakDays) 天")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
.padding(.vertical, DS.Spacing.xs)
|
|
}
|
|
}
|