ios-projects/AIStudyApp/AIStudyApp/Features/AI/AIFeedbackPageView.swift
WangDL a05dd09902 refactor(ios): migrate NavigationLink to value-based routing, add Dynamic Type support, fix gesture conflicts
- Replace all deprecated NavigationLink(destination:) with NavigationLink(value: Route)
- Add Route enum with navigationDestination mapping in new Core/Navigation/
- Extract 7 new sub-page files (AIChatPage, AIFeedbackPageView, RecallTestPage, WeakPointsPage, FeedbackFormView, GoalSettingDetailView, MethodPreferenceView)
- Add @ScaledMetric-based zxFontScaled modifier for Dynamic Type
- Fix ZXPressModifier gesture conflict with ScrollView using onLongPressGesture
- Enlarge touch targets from 36pt to 44pt
- Add accessibility labels to TextField and other controls

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 15:21:36 +08:00

108 lines
6.6 KiB
Swift

import SwiftUI
struct AIFeedbackPageView: View {
@State private var navigateToChat = false
@State private var isAnalyzing = true
var body: some View {
ZStack {
Color.zxBg0.ignoresSafeArea()
if isAnalyzing {
ZXAIAnalysisProgress(steps: [
"解析你的回答结构…",
"对比知识库标准答案…",
"评估概念理解深度…",
"生成个性化反馈…"
])
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
withAnimation(.easeOut(duration: 0.4)) { isAnalyzing = false }
}
}
} else {
ScrollView {
VStack(spacing: 16) {
HStack(spacing: 20) {
ZStack {
Circle().trim(from: 0, to: 0.78).stroke(ZXGradient.brand, style: StrokeStyle(lineWidth: 10, lineCap: .round)).rotationEffect(.degrees(-90)).frame(width: 80, height: 80)
VStack(spacing: 0) {
Text("78").font(.system(size: 22, weight: .heavy)).foregroundColor(Color.zxPurple)
Text("/ 100").font(.system(size: 9)).foregroundColor(Color.zxF04)
}
}
VStack(alignment: .leading, spacing: 2) {
Text("良好掌握").zxFontScaled(size: 18, weight: .heavy).foregroundColor(Color.zxF0)
Text("理解核心概念,但缺少理论深度和解决方案").zxFontScaled(size: 12).foregroundColor(Color.zxF0045).lineSpacing(4)
}
Spacer()
}
.padding(20)
.background(ZXGradient.feedbackScore)
.clipShape(RoundedRectangle(cornerRadius: 20))
.overlay(RoundedRectangle(cornerRadius: 20).stroke(Color(hex: "#7C6EFA", opacity: 0.2), lineWidth: 1))
VStack(alignment: .leading, spacing: 8) {
Text("你的回答").font(.system(size: 13, weight: .semibold)).foregroundColor(Color.zxF04)
Text("过拟合就像一个学生只会「死记硬背」考题,而不是真正理解知识…").zxFontScaled(size: 13).foregroundColor(Color.zxF007).lineSpacing(6).padding(14).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder006, lineWidth: 1))
}
VStack(alignment: .leading, spacing: 8) {
HStack(spacing: 8) {
Image(systemName: "checkmark.circle.fill").foregroundColor(Color.zxGreen)
Text("答对的部分").font(.system(size: 14, weight: .bold)).foregroundColor(Color.zxF0)
}
ForEach(["正确识别出过拟合是\"记住训练数据\"而非\"学习规律\"", "使用了死记硬背类比,方向正确且贴切"], id: \.self) { s in
HStack(alignment: .top, spacing: 12) {
Circle().fill(Color.zxGreen).frame(width: 6, height: 6).padding(.top, 6)
Text(s).zxFontScaled(size: 13).foregroundColor(Color(hex: "#F0F0FF", opacity: 0.75)).lineSpacing(4)
}
.padding(12)
.background(Color(hex: "#34D399", opacity: 0.07))
.clipShape(RoundedRectangle(cornerRadius: 12))
.overlay(RoundedRectangle(cornerRadius: 12).stroke(Color(hex: "#34D399", opacity: 0.18), lineWidth: 1))
}
}
NavigationLink(value: Route.studyHome) {
Label("加入待巩固,安排间隔复习", systemImage: "bolt.fill")
.font(.system(size: 14, weight: .bold))
.foregroundColor(.white)
.frame(maxWidth: .infinity).frame(height: 52)
.background(ZXGradient.ctaPurple)
.clipShape(RoundedRectangle(cornerRadius: 16))
.shadow(color: Color(hex: "#7C6EFA", opacity: 0.3), radius: 24)
}
HStack(spacing: 12) {
NavigationLink(value: Route.aiChat) {
HStack(spacing: 4) {
Text("深入提问").font(.system(size: 13))
Image(systemName: "chevron.right").font(.system(size: 14))
}
.foregroundColor(Color.zxF05)
.frame(maxWidth: .infinity).frame(height: 44)
.background(Color.zxFill005)
.clipShape(RoundedRectangle(cornerRadius: 14))
.overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1))
}
NavigationLink(value: Route.dailyThinking) {
HStack(spacing: 4) {
Text("再来一题").font(.system(size: 13))
Image(systemName: "chevron.right").font(.system(size: 14))
}
.foregroundColor(Color.zxF05)
.frame(maxWidth: .infinity).frame(height: 44)
.background(Color.zxFill005)
.clipShape(RoundedRectangle(cornerRadius: 14))
.overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1))
}
}
}
.padding(.horizontal, 20).padding(.top, 8).padding(.bottom, 80)
}
.scrollIndicators(.hidden)
.transition(.opacity.combined(with: .scale(scale: 0.95)))
}
}
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.hidden, for: .navigationBar)
}
}