83 lines
3.4 KiB
Swift
83 lines
3.4 KiB
Swift
import SwiftUI
|
|
import WidgetKit
|
|
import Bedrock
|
|
|
|
struct MediumWidgetView: View {
|
|
let entry: WidgetEntry
|
|
|
|
var body: some View {
|
|
HStack(spacing: 0) {
|
|
// Left side: Progress & Streak
|
|
VStack(spacing: Design.Spacing.medium) {
|
|
ZStack {
|
|
Circle()
|
|
.stroke(AppTextColors.primary.opacity(0.1), lineWidth: 8)
|
|
Circle()
|
|
.trim(from: 0, to: entry.completionRate)
|
|
.stroke(AppAccent.primary, style: StrokeStyle(lineWidth: 8, lineCap: .round))
|
|
.rotationEffect(.degrees(-90))
|
|
|
|
VStack(spacing: 0) {
|
|
Text("\(Int(entry.completionRate * 100))%")
|
|
.styled(.heading, emphasis: .custom(AppTextColors.primary))
|
|
Text(String(localized: "Today"))
|
|
.styled(.caption, emphasis: .custom(AppTextColors.secondary))
|
|
}
|
|
}
|
|
.frame(width: 72, height: 72)
|
|
|
|
HStack(spacing: Design.Spacing.xSmall) {
|
|
Image(systemName: "flame.fill")
|
|
.foregroundColor(AppAccent.primary)
|
|
.font(.system(size: 14))
|
|
Text("\(entry.currentStreak)d")
|
|
.styled(.captionEmphasis, emphasis: .custom(AppTextColors.primary))
|
|
}
|
|
}
|
|
.frame(width: 110)
|
|
|
|
// Right side: Habits
|
|
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
|
if entry.nextHabits.isEmpty {
|
|
WidgetEmptyStateView(
|
|
iconSize: .card,
|
|
title: String(localized: "No rituals now"),
|
|
subtitle: entry.currentTimeOfDay,
|
|
symbolName: entry.currentTimeOfDaySymbol,
|
|
timeRange: entry.currentTimeOfDayRange,
|
|
nextRitual: entry.nextRitualInfo,
|
|
isCompact: true
|
|
)
|
|
} else {
|
|
Text(String(localized: "Next Habits"))
|
|
.styled(.captionEmphasis, emphasis: .custom(AppTextColors.secondary))
|
|
|
|
VStack(alignment: .leading, spacing: Design.Spacing.small) {
|
|
ForEach(entry.nextHabits.prefix(3)) { habit in
|
|
HStack(spacing: Design.Spacing.small) {
|
|
Image(systemName: habit.isCompleted ? "checkmark.circle.fill" : habit.symbolName)
|
|
.foregroundColor(habit.isCompleted ? .green : AppAccent.primary)
|
|
.font(.system(size: 14))
|
|
.frame(width: 20)
|
|
|
|
Text(habit.title)
|
|
.styled(.subheading, emphasis: .custom(AppTextColors.primary))
|
|
.lineLimit(1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Spacer()
|
|
}
|
|
.padding(.vertical, Design.Spacing.large)
|
|
.padding(.trailing, Design.Spacing.medium)
|
|
|
|
Spacer()
|
|
}
|
|
.containerBackground(for: .widget) {
|
|
AppSurface.primary
|
|
}
|
|
}
|
|
}
|