Scope week tests to the selected course

WeekTestView filtered decks and TestResults by weekNumber alone, so Week 3
of any course pulled content from every course's Week 3 simultaneously.
Thread courseName through the navigation destination, quiz view, and
TestResult model so quiz cards, score history, and focus-area missed items
are all scoped to the active course.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-11 18:17:30 -05:00
parent f59d81fc5a
commit 644dbb7230
4 changed files with 41 additions and 10 deletions

View File

@@ -9,6 +9,7 @@ struct MissedCourseItem: Codable, Hashable, Sendable {
@Model
final class TestResult {
var id: String = ""
var courseName: String = ""
var weekNumber: Int = 0
var quizType: String = ""
var totalQuestions: Int = 0
@@ -25,8 +26,9 @@ final class TestResult {
return Int(round(Double(correctCount) / Double(totalQuestions) * 100))
}
init(weekNumber: Int, quizType: String, totalQuestions: Int, correctCount: Int, missedItems: [MissedCourseItem]) {
init(courseName: String, weekNumber: Int, quizType: String, totalQuestions: Int, correctCount: Int, missedItems: [MissedCourseItem]) {
self.id = UUID().uuidString
self.courseName = courseName
self.weekNumber = weekNumber
self.quizType = quizType
self.totalQuestions = totalQuestions
@@ -35,8 +37,9 @@ final class TestResult {
self.missedItems = missedItems
}
convenience init(weekNumber: Int, quizType: String, totalQuestions: Int, correctCount: Int, missedFronts: [String], missedBacks: [String]) {
convenience init(courseName: String, weekNumber: Int, quizType: String, totalQuestions: Int, correctCount: Int, missedFronts: [String], missedBacks: [String]) {
self.init(
courseName: courseName,
weekNumber: weekNumber,
quizType: quizType,
totalQuestions: totalQuestions,

View File

@@ -6,6 +6,7 @@ import PencilKit
struct CourseQuizView: View {
let cards: [VocabCard]
let quizType: QuizType
let courseName: String
let weekNumber: Int
let isFocusMode: Bool
@@ -508,6 +509,7 @@ struct CourseQuizView: View {
private func saveResult() {
let result = TestResult(
courseName: courseName,
weekNumber: weekNumber,
quizType: quizType.rawValue,
totalQuestions: shuffledCards.count,
@@ -521,7 +523,13 @@ struct CourseQuizView: View {
#Preview {
NavigationStack {
CourseQuizView(cards: [], quizType: .mcEsToEn, weekNumber: 1, isFocusMode: false)
CourseQuizView(
cards: [],
quizType: .mcEsToEn,
courseName: "LanGo Spanish | Beginner I",
weekNumber: 1,
isFocusMode: false
)
}
.modelContainer(for: [TestResult.self, VocabCard.self], inMemory: true)
}

View File

@@ -31,7 +31,9 @@ struct CourseView: View {
}
private func bestScore(for week: Int) -> Int? {
let results = testResults.filter { $0.weekNumber == week }
let results = testResults.filter {
$0.courseName == activeCourse && $0.weekNumber == week
}
guard !results.isEmpty else { return nil }
return results.map(\.scorePercent).max()
}
@@ -70,7 +72,7 @@ struct CourseView: View {
ForEach(weekGroups, id: \.week) { week, weekDecks in
Section {
// Test button
NavigationLink(value: week) {
NavigationLink(value: WeekTestDestination(courseName: activeCourse, weekNumber: week)) {
HStack(spacing: 12) {
Image(systemName: "pencil.and.list.clipboard")
.font(.title3)
@@ -112,8 +114,8 @@ struct CourseView: View {
.navigationDestination(for: CourseDeck.self) { deck in
DeckStudyView(deck: deck)
}
.navigationDestination(for: Int.self) { week in
WeekTestView(weekNumber: week)
.navigationDestination(for: WeekTestDestination.self) { dest in
WeekTestView(courseName: dest.courseName, weekNumber: dest.weekNumber)
}
}
}
@@ -123,6 +125,13 @@ struct CourseView: View {
}
}
// MARK: - Navigation
struct WeekTestDestination: Hashable {
let courseName: String
let weekNumber: Int
}
// MARK: - Deck Row
private struct DeckRowView: View {

View File

@@ -3,6 +3,7 @@ import SharedModels
import SwiftData
struct WeekTestView: View {
let courseName: String
let weekNumber: Int
@Environment(\.modelContext) private var modelContext
@Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
@@ -60,6 +61,7 @@ struct WeekTestView: View {
CourseQuizView(
cards: weekCards,
quizType: type,
courseName: courseName,
weekNumber: weekNumber,
isFocusMode: false
)
@@ -139,6 +141,7 @@ struct WeekTestView: View {
CourseQuizView(
cards: focusCards,
quizType: .mcEsToEn,
courseName: courseName,
weekNumber: weekNumber,
isFocusMode: true
)
@@ -206,7 +209,11 @@ struct WeekTestView: View {
}
private func loadCards() {
let weekDecks = allDecks.filter { $0.weekNumber == weekNumber && !$0.isReversed }
let course = courseName
let week = weekNumber
let weekDecks = allDecks.filter {
$0.courseName == course && $0.weekNumber == week && !$0.isReversed
}
let deckIds = weekDecks.map(\.id)
var cards: [VocabCard] = []
for deckId in deckIds {
@@ -221,8 +228,12 @@ struct WeekTestView: View {
}
private func loadResults() {
let course = courseName
let week = weekNumber
let descriptor = FetchDescriptor<TestResult>(
predicate: #Predicate<TestResult> { $0.weekNumber == weekNumber },
predicate: #Predicate<TestResult> {
$0.courseName == course && $0.weekNumber == week
},
sortBy: [SortDescriptor(\TestResult.dateTaken, order: .reverse)]
)
weekResults = (try? cloudModelContext.fetch(descriptor)) ?? []
@@ -237,7 +248,7 @@ struct WeekTestView: View {
#Preview {
NavigationStack {
WeekTestView(weekNumber: 1)
WeekTestView(courseName: "LanGo Spanish | Beginner I", weekNumber: 1)
}
.modelContainer(for: [TestResult.self, CourseDeck.self, VocabCard.self], inMemory: true)
}