TeachMate/TeachMate/Views/SemesterFormView.swift

208 lines
8.5 KiB
Swift

//
// SemesterFormView.swift
// TeachMate
//
// Created by Hongli on 2025/3/12.
//
import SwiftUI
import SwiftData
struct SemesterFormView: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var modelContext
@Environment(\.colorScheme) private var colorScheme
@State private var title: String = ""
@State private var startDate: Date = Date()
@State private var endDate: Date = Date()
@State private var weeksCount: Int = 18
@State private var showingAlert = false
@State private var alertMessage = ""
// Calculate the end of the week (Sunday) for a given date
private func endOfWeek(for date: Date) -> Date {
let calendar = Calendar.current
let components = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: date)
guard let sunday = calendar.date(from: components) else { return date }
// Add 6 days to get to Sunday (assuming first day of week is Monday)
return calendar.date(byAdding: .day, value: 6, to: sunday) ?? date
}
// Calculate the end date (last Sunday of the semester)
private func calculateEndDate() -> Date {
let calendar = Calendar.current
// Add (weeksCount - 1) weeks to the start date to get to the beginning of the last week
guard let lastWeekStart = calendar.date(byAdding: .day, value: (weeksCount - 1) * 7, to: startDate) else {
return endDate
}
// Get the Sunday of the last week
return endOfWeek(for: lastWeekStart)
}
// Format date for display
private func formattedDate(_ date: Date) -> String {
let formatter = DateFormatter()
formatter.dateStyle = .medium
return formatter.string(from: date)
}
var body: some View {
NavigationStack {
ZStack {
// Background
(colorScheme == .dark ? Color.black : Color.gray.opacity(0.1))
.ignoresSafeArea()
// Main content with horizontal layout
HStack(spacing: 0) {
// Left side - Form content
ScrollView {
VStack(spacing: 24) {
// Title Section
FormSection(title: "学期标题") {
VStack(alignment: .leading, spacing: 8) {
TextField("请输入标题", text: $title)
.textFieldStyle(RoundedBorderTextFieldStyle())
.autocorrectionDisabled()
.frame(maxWidth: .infinity)
Text("标题格式: YYYY-YYYY-N")
.font(.caption)
.foregroundStyle(.secondary)
}
.frame(maxWidth: .infinity)
}
// Combined Teaching Weeks Section
FormSection(title: "教学周") {
VStack(spacing: 16) {
// Weeks count
HStack {
Text("周数:")
.foregroundStyle(.secondary)
Spacer()
Picker("周数", selection: $weeksCount) {
ForEach(1...30, id: \.self) { week in
Text("\(week)").tag(week)
}
}
.pickerStyle(.menu)
.onChange(of: weeksCount) { _, _ in
// Update end date when weeks count changes
endDate = calculateEndDate()
}
}
Divider()
// Start date
HStack {
Text("开始日期:")
.foregroundStyle(.secondary)
Spacer()
DatePicker(
"",
selection: $startDate,
displayedComponents: [.date]
)
.labelsHidden()
.onChange(of: startDate) { _, _ in
// Update end date when start date changes
endDate = calculateEndDate()
}
}
}
.frame(maxWidth: .infinity)
}
}
.padding()
.frame(maxWidth: .infinity)
}
.frame(minWidth: 300, idealWidth: 350, maxWidth: .infinity)
// Vertical divider
Divider()
.padding(.vertical)
// Right side - Summary
VStack {
FormSection(title: "学期概览") {
VStack(alignment: .leading, spacing: 12) {
SummaryRow(label: "标题", value: title.isEmpty ? "未设置" : title)
SummaryRow(label: "周数", value: "\(weeksCount)")
SummaryRow(label: "开始日期", value: formattedDate(startDate))
SummaryRow(label: "结束日期", value: formattedDate(endDate))
SummaryRow(
label: "总时长",
value: "\(Calendar.current.dateComponents([.day], from: startDate, to: endDate).day ?? 0 + 1)"
)
}
}
Spacer()
}
.padding()
.frame(minWidth: 250, idealWidth: 300, maxWidth: .infinity)
.background(colorScheme == .dark ? Color.black : Color.white)
}
.frame(minWidth: 600, idealWidth: 700, maxHeight: .infinity)
}
.navigationTitle("添加学期")
.toolbarRole(.editor)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("取消") {
dismiss()
}
}
ToolbarItem(placement: .confirmationAction) {
Button("保存") {
saveSemester()
}
}
}
.onAppear {
// Set default end date
endDate = calculateEndDate()
}
.alert("错误", isPresented: $showingAlert) {
Button("确定", role: .cancel) { }
} message: {
Text(alertMessage)
}
}
}
private func saveSemester() {
// Validate inputs
if title.isEmpty {
alertMessage = "请输入学期标题"
showingAlert = true
return
}
// Create and save the semester
let semester = Semester(
title: title,
startDate: startDate,
endDate: endDate,
weeksCount: weeksCount
)
modelContext.insert(semester)
dismiss()
}
}
#Preview {
SemesterFormView()
.modelContainer(PreviewData.createSemesterContainer())
}