208 lines
8.5 KiB
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())
|
|
}
|