Enrich test data, fix multi-page PDF export, and polish UI
- Populate debug test data with random notes, guided reflections, and weather - Fix PDF export to use UIPrintPageRenderer for proper multi-page pagination - Add journal/reflection indicator icons to day list entry cells - Fix weather card icon contrast by using secondarySystemBackground - Align Generate Report and Export PDF button widths in ReportsView Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -63,15 +63,15 @@ extension DataController {
|
||||
|
||||
for idx in 1..<1000 {
|
||||
let date = Calendar.current.date(byAdding: .day, value: -idx, to: Date())!
|
||||
var moodValue = Int.random(in: 3...4)
|
||||
if Int.random(in: 0...400) % 5 == 0 {
|
||||
moodValue = Int.random(in: 0...4)
|
||||
}
|
||||
let mood = Self.randomMood()
|
||||
|
||||
let entry = MoodEntryModel(
|
||||
forDate: date,
|
||||
mood: Mood(rawValue: moodValue) ?? .average,
|
||||
entryType: .listView
|
||||
mood: mood,
|
||||
entryType: .listView,
|
||||
notes: Self.randomNotes(),
|
||||
weatherJSON: Self.randomWeatherJSON(for: date),
|
||||
reflectionJSON: Self.randomReflectionJSON(for: mood, on: date)
|
||||
)
|
||||
modelContext.insert(entry)
|
||||
}
|
||||
@@ -85,15 +85,15 @@ extension DataController {
|
||||
|
||||
for idx in 1...730 {
|
||||
let date = Calendar.current.date(byAdding: .day, value: -idx, to: Date())!
|
||||
var moodValue = Int.random(in: 3...4)
|
||||
if Int.random(in: 0...400) % 5 == 0 {
|
||||
moodValue = Int.random(in: 0...4)
|
||||
}
|
||||
let mood = Self.randomMood()
|
||||
|
||||
let entry = MoodEntryModel(
|
||||
forDate: date,
|
||||
mood: Mood(rawValue: moodValue) ?? .average,
|
||||
entryType: .listView
|
||||
mood: mood,
|
||||
entryType: .listView,
|
||||
notes: Self.randomNotes(),
|
||||
weatherJSON: Self.randomWeatherJSON(for: date),
|
||||
reflectionJSON: Self.randomReflectionJSON(for: mood, on: date)
|
||||
)
|
||||
modelContext.insert(entry)
|
||||
}
|
||||
@@ -102,6 +102,121 @@ extension DataController {
|
||||
}
|
||||
#endif
|
||||
|
||||
private static func randomMood() -> Mood {
|
||||
var moodValue = Int.random(in: 3...4)
|
||||
if Int.random(in: 0...400) % 5 == 0 {
|
||||
moodValue = Int.random(in: 0...4)
|
||||
}
|
||||
return Mood(rawValue: moodValue) ?? .average
|
||||
}
|
||||
|
||||
// ~40% of entries get notes
|
||||
private static func randomNotes() -> String? {
|
||||
guard Bool.random() && Bool.random() == false else { return nil }
|
||||
return sampleNotes.randomElement()
|
||||
}
|
||||
|
||||
private static let sampleNotes: [String] = [
|
||||
"Had a productive morning and got a lot done.",
|
||||
"Went for a long walk in the park today.",
|
||||
"Feeling grateful for the little things.",
|
||||
"Tough meeting at work but pushed through.",
|
||||
"Spent quality time with family this evening.",
|
||||
"Couldn't sleep well last night, feeling tired.",
|
||||
"Great workout at the gym today!",
|
||||
"Read a really interesting book chapter.",
|
||||
"Cooked a new recipe and it turned out great.",
|
||||
"Feeling a bit anxious about tomorrow.",
|
||||
"Had coffee with an old friend, felt wonderful.",
|
||||
"Rainy day but cozy inside with a good movie.",
|
||||
"Got some bad news, trying to stay positive.",
|
||||
"Meditation session helped clear my mind.",
|
||||
"Busy day but managed to stay focused.",
|
||||
"Enjoyed a quiet evening at home.",
|
||||
"Felt overwhelmed by my to-do list.",
|
||||
"Beautiful sunset on the drive home.",
|
||||
"Tried journaling for the first time in a while.",
|
||||
"Had a really meaningful conversation today.",
|
||||
]
|
||||
|
||||
// ~25% of entries get guided reflections
|
||||
private static func randomReflectionJSON(for mood: Mood, on date: Date) -> String? {
|
||||
guard Int.random(in: 0...3) == 0 else { return nil }
|
||||
let category = MoodCategory(from: mood)
|
||||
let questions = GuidedReflection.questions(for: category)
|
||||
let answers = sampleAnswers(for: category)
|
||||
let responses = questions.enumerated().map { index, question in
|
||||
GuidedReflection.Response(
|
||||
id: index,
|
||||
question: question,
|
||||
answer: answers[index % answers.count]
|
||||
)
|
||||
}
|
||||
let reflection = GuidedReflection(
|
||||
moodCategory: category,
|
||||
responses: responses,
|
||||
completedAt: date
|
||||
)
|
||||
return reflection.encode()
|
||||
}
|
||||
|
||||
private static func sampleAnswers(for category: MoodCategory) -> [String] {
|
||||
switch category {
|
||||
case .positive:
|
||||
return [
|
||||
"I felt a sense of calm and contentment throughout the day.",
|
||||
"Connecting with a friend really lifted my spirits.",
|
||||
"I want to keep making time for the things that bring me joy.",
|
||||
]
|
||||
case .neutral:
|
||||
return [
|
||||
"A mix of emotions today, nothing too strong in either direction.",
|
||||
"Work was steady but unremarkable.",
|
||||
"I'd like to be more intentional about how I spend my evenings.",
|
||||
"Maybe adding a short walk after lunch could help.",
|
||||
]
|
||||
case .negative:
|
||||
return [
|
||||
"I've been worrying about things outside my control.",
|
||||
"A stressful interaction this morning set the tone for the day.",
|
||||
"I think I need some quiet time to recharge.",
|
||||
"Taking a few deep breaths and stepping away from screens.",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private static let weatherConditions: [(symbol: String, condition: String)] = [
|
||||
("sun.max.fill", "Clear"),
|
||||
("cloud.sun.fill", "Partly Cloudy"),
|
||||
("cloud.fill", "Cloudy"),
|
||||
("cloud.rain.fill", "Rain"),
|
||||
("cloud.heavyrain.fill", "Heavy Rain"),
|
||||
("cloud.drizzle.fill", "Drizzle"),
|
||||
("cloud.bolt.fill", "Thunderstorms"),
|
||||
("cloud.snow.fill", "Snow"),
|
||||
("cloud.fog.fill", "Foggy"),
|
||||
("wind", "Windy"),
|
||||
("sun.haze.fill", "Hazy"),
|
||||
]
|
||||
|
||||
private static func randomWeatherJSON(for date: Date) -> String? {
|
||||
let condition = weatherConditions.randomElement()!
|
||||
let high = Double.random(in: 5...35)
|
||||
let low = high - Double.random(in: 5...15)
|
||||
let weather = WeatherData(
|
||||
conditionSymbol: condition.symbol,
|
||||
condition: condition.condition,
|
||||
temperature: (high + low) / 2.0,
|
||||
highTemperature: high,
|
||||
lowTemperature: low,
|
||||
humidity: Double.random(in: 0.2...0.95),
|
||||
latitude: 37.7749,
|
||||
longitude: -122.4194,
|
||||
fetchedAt: date
|
||||
)
|
||||
return weather.encode()
|
||||
}
|
||||
|
||||
func longestStreak() -> [MoodEntryModel] {
|
||||
let descriptor = FetchDescriptor<MoodEntryModel>(
|
||||
sortBy: [SortDescriptor(\.forDate, order: .forward)]
|
||||
|
||||
Reference in New Issue
Block a user