Compare commits
2 Commits
f59d81fc5a
...
4e874f60d7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e874f60d7 | ||
|
|
644dbb7230 |
@@ -9,6 +9,7 @@ struct MissedCourseItem: Codable, Hashable, Sendable {
|
|||||||
@Model
|
@Model
|
||||||
final class TestResult {
|
final class TestResult {
|
||||||
var id: String = ""
|
var id: String = ""
|
||||||
|
var courseName: String = ""
|
||||||
var weekNumber: Int = 0
|
var weekNumber: Int = 0
|
||||||
var quizType: String = ""
|
var quizType: String = ""
|
||||||
var totalQuestions: Int = 0
|
var totalQuestions: Int = 0
|
||||||
@@ -25,8 +26,9 @@ final class TestResult {
|
|||||||
return Int(round(Double(correctCount) / Double(totalQuestions) * 100))
|
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.id = UUID().uuidString
|
||||||
|
self.courseName = courseName
|
||||||
self.weekNumber = weekNumber
|
self.weekNumber = weekNumber
|
||||||
self.quizType = quizType
|
self.quizType = quizType
|
||||||
self.totalQuestions = totalQuestions
|
self.totalQuestions = totalQuestions
|
||||||
@@ -35,8 +37,9 @@ final class TestResult {
|
|||||||
self.missedItems = missedItems
|
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(
|
self.init(
|
||||||
|
courseName: courseName,
|
||||||
weekNumber: weekNumber,
|
weekNumber: weekNumber,
|
||||||
quizType: quizType,
|
quizType: quizType,
|
||||||
totalQuestions: totalQuestions,
|
totalQuestions: totalQuestions,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import PencilKit
|
|||||||
struct CourseQuizView: View {
|
struct CourseQuizView: View {
|
||||||
let cards: [VocabCard]
|
let cards: [VocabCard]
|
||||||
let quizType: QuizType
|
let quizType: QuizType
|
||||||
|
let courseName: String
|
||||||
let weekNumber: Int
|
let weekNumber: Int
|
||||||
let isFocusMode: Bool
|
let isFocusMode: Bool
|
||||||
|
|
||||||
@@ -508,6 +509,7 @@ struct CourseQuizView: View {
|
|||||||
|
|
||||||
private func saveResult() {
|
private func saveResult() {
|
||||||
let result = TestResult(
|
let result = TestResult(
|
||||||
|
courseName: courseName,
|
||||||
weekNumber: weekNumber,
|
weekNumber: weekNumber,
|
||||||
quizType: quizType.rawValue,
|
quizType: quizType.rawValue,
|
||||||
totalQuestions: shuffledCards.count,
|
totalQuestions: shuffledCards.count,
|
||||||
@@ -521,7 +523,13 @@ struct CourseQuizView: View {
|
|||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
NavigationStack {
|
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)
|
.modelContainer(for: [TestResult.self, VocabCard.self], inMemory: true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ struct CourseView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func bestScore(for week: Int) -> Int? {
|
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 }
|
guard !results.isEmpty else { return nil }
|
||||||
return results.map(\.scorePercent).max()
|
return results.map(\.scorePercent).max()
|
||||||
}
|
}
|
||||||
@@ -70,7 +72,7 @@ struct CourseView: View {
|
|||||||
ForEach(weekGroups, id: \.week) { week, weekDecks in
|
ForEach(weekGroups, id: \.week) { week, weekDecks in
|
||||||
Section {
|
Section {
|
||||||
// Test button
|
// Test button
|
||||||
NavigationLink(value: week) {
|
NavigationLink(value: WeekTestDestination(courseName: activeCourse, weekNumber: week)) {
|
||||||
HStack(spacing: 12) {
|
HStack(spacing: 12) {
|
||||||
Image(systemName: "pencil.and.list.clipboard")
|
Image(systemName: "pencil.and.list.clipboard")
|
||||||
.font(.title3)
|
.font(.title3)
|
||||||
@@ -112,8 +114,8 @@ struct CourseView: View {
|
|||||||
.navigationDestination(for: CourseDeck.self) { deck in
|
.navigationDestination(for: CourseDeck.self) { deck in
|
||||||
DeckStudyView(deck: deck)
|
DeckStudyView(deck: deck)
|
||||||
}
|
}
|
||||||
.navigationDestination(for: Int.self) { week in
|
.navigationDestination(for: WeekTestDestination.self) { dest in
|
||||||
WeekTestView(weekNumber: week)
|
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
|
// MARK: - Deck Row
|
||||||
|
|
||||||
private struct DeckRowView: View {
|
private struct DeckRowView: View {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import SharedModels
|
|||||||
import SwiftData
|
import SwiftData
|
||||||
|
|
||||||
struct WeekTestView: View {
|
struct WeekTestView: View {
|
||||||
|
let courseName: String
|
||||||
let weekNumber: Int
|
let weekNumber: Int
|
||||||
@Environment(\.modelContext) private var modelContext
|
@Environment(\.modelContext) private var modelContext
|
||||||
@Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
|
@Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
|
||||||
@@ -60,6 +61,7 @@ struct WeekTestView: View {
|
|||||||
CourseQuizView(
|
CourseQuizView(
|
||||||
cards: weekCards,
|
cards: weekCards,
|
||||||
quizType: type,
|
quizType: type,
|
||||||
|
courseName: courseName,
|
||||||
weekNumber: weekNumber,
|
weekNumber: weekNumber,
|
||||||
isFocusMode: false
|
isFocusMode: false
|
||||||
)
|
)
|
||||||
@@ -139,6 +141,7 @@ struct WeekTestView: View {
|
|||||||
CourseQuizView(
|
CourseQuizView(
|
||||||
cards: focusCards,
|
cards: focusCards,
|
||||||
quizType: .mcEsToEn,
|
quizType: .mcEsToEn,
|
||||||
|
courseName: courseName,
|
||||||
weekNumber: weekNumber,
|
weekNumber: weekNumber,
|
||||||
isFocusMode: true
|
isFocusMode: true
|
||||||
)
|
)
|
||||||
@@ -206,7 +209,11 @@ struct WeekTestView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func loadCards() {
|
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)
|
let deckIds = weekDecks.map(\.id)
|
||||||
var cards: [VocabCard] = []
|
var cards: [VocabCard] = []
|
||||||
for deckId in deckIds {
|
for deckId in deckIds {
|
||||||
@@ -221,8 +228,12 @@ struct WeekTestView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func loadResults() {
|
private func loadResults() {
|
||||||
|
let course = courseName
|
||||||
|
let week = weekNumber
|
||||||
let descriptor = FetchDescriptor<TestResult>(
|
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)]
|
sortBy: [SortDescriptor(\TestResult.dateTaken, order: .reverse)]
|
||||||
)
|
)
|
||||||
weekResults = (try? cloudModelContext.fetch(descriptor)) ?? []
|
weekResults = (try? cloudModelContext.fetch(descriptor)) ?? []
|
||||||
@@ -237,7 +248,7 @@ struct WeekTestView: View {
|
|||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
WeekTestView(weekNumber: 1)
|
WeekTestView(courseName: "LanGo Spanish | Beginner I", weekNumber: 1)
|
||||||
}
|
}
|
||||||
.modelContainer(for: [TestResult.self, CourseDeck.self, VocabCard.self], inMemory: true)
|
.modelContainer(for: [TestResult.self, CourseDeck.self, VocabCard.self], inMemory: true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ struct DashboardView: View {
|
|||||||
@State private var dailyLogs: [DailyLog] = []
|
@State private var dailyLogs: [DailyLog] = []
|
||||||
@State private var testResults: [TestResult] = []
|
@State private var testResults: [TestResult] = []
|
||||||
@State private var reviewCards: [ReviewCard] = []
|
@State private var reviewCards: [ReviewCard] = []
|
||||||
|
@State private var showingSettings = false
|
||||||
|
|
||||||
private var cloudModelContext: ModelContext { cloudModelContextProvider() }
|
private var cloudModelContext: ModelContext { cloudModelContextProvider() }
|
||||||
|
|
||||||
@@ -33,6 +34,19 @@ struct DashboardView: View {
|
|||||||
.adaptiveContainer(maxWidth: 800)
|
.adaptiveContainer(maxWidth: 800)
|
||||||
}
|
}
|
||||||
.navigationTitle("Dashboard")
|
.navigationTitle("Dashboard")
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .topBarTrailing) {
|
||||||
|
Button {
|
||||||
|
showingSettings = true
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "gearshape")
|
||||||
|
}
|
||||||
|
.accessibilityLabel("Settings")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sheet(isPresented: $showingSettings) {
|
||||||
|
SettingsView()
|
||||||
|
}
|
||||||
.onAppear(perform: loadData)
|
.onAppear(perform: loadData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ struct MainTabView: View {
|
|||||||
Tab("Course", systemImage: "list.clipboard") {
|
Tab("Course", systemImage: "list.clipboard") {
|
||||||
CourseView()
|
CourseView()
|
||||||
}
|
}
|
||||||
Tab("Settings", systemImage: "gearshape") {
|
|
||||||
SettingsView()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user