Files
ios-client/IosClientKit/Sources/FeaturePlan/PlanSubmitScreen.swift
2026-09-15 14:35:52 +08:00

136 lines
5.0 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import SwiftUI
import CoreModel
import CoreUI
import DesignSystem
public struct PlanSubmitScreen: View {
private let viewModel: PlanSubmitViewModel
private let type: PlanType
private let periodKey: String
@State private var content = ""
@Environment(\.dismiss) private var dismiss
public init(viewModel: PlanSubmitViewModel, type: PlanType, periodKey: String) {
self.viewModel = viewModel
self.type = type
self.periodKey = periodKey
}
public var body: some View {
contentView
.navigationTitle("\(type.label) · \(periodKey)")
.task { viewModel.load() }
.onChange(of: viewModel.uiState) { _, newState in
if case .success(let data) = newState, content.isEmpty, !data.content.isEmpty {
content = data.content
}
}
.onChange(of: viewModel.saved) { _, saved in
if saved { dismiss() }
}
}
@ViewBuilder
private var contentView: some View {
switch viewModel.uiState {
case .loading:
LoadingView()
case .error(let message):
ErrorView(message: message) { viewModel.load() }
case .success(let data):
submitContent(data)
}
}
private func submitContent(_ data: PlanSubmitData) -> some View {
ScrollView {
VStack(spacing: DS.Spacing.md) {
if !data.canSubmit, let message = data.message {
Text(message)
.font(.caption)
.foregroundStyle(DS.Color.brandMuted)
.frame(maxWidth: .infinity, alignment: .leading)
}
VStack(alignment: .trailing, spacing: DS.Spacing.xs) {
TextEditor(text: $content)
.frame(minHeight: 120)
.scrollContentBackground(.hidden)
.padding(DS.Spacing.sm)
.background(data.canSubmit ? DS.Color.brandPaper : DS.Color.brandChip)
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
.overlay(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.stroke(DS.Color.disabled, lineWidth: 1)
)
Text("\(content.count)/1000")
.font(.caption)
.foregroundStyle(DS.Color.faintText)
}
HStack {
Text("+ 添加图片(\(data.attachments.count)/4)")
.font(.subheadline)
.foregroundStyle(data.canSubmit ? DS.Color.brandGold : DS.Color.disabled)
Spacer()
}
.padding(DS.Spacing.sm)
.frame(maxWidth: .infinity)
.background(Color.white)
.overlay(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.stroke(data.canSubmit ? DS.Color.brandGold : DS.Color.disabled, lineWidth: 1)
)
Button(saveTitle(data)) {
viewModel.save(content: content)
}
.buttonStyle(.borderedProminent)
.disabled(!(data.canSubmit && !content.isEmpty && !viewModel.saving))
HistorySection(history: data.history)
}
.padding(DS.Spacing.md)
}
.background(DS.Color.brandPaper)
}
private func saveTitle(_ data: PlanSubmitData) -> String {
if !data.canSubmit { return "不可提交" }
if data.checked { return "保存修改" }
return "保存计划"
}
}
private struct HistorySection: View {
let history: [MyPlanRecord]
var body: some View {
VStack(alignment: .leading, spacing: DS.Spacing.sm) {
Text("历史计划")
.font(.subheadline.bold())
.foregroundStyle(DS.Color.brandDark)
if history.isEmpty {
EmptyStateView(title: "暂无历史计划", systemImage: "doc")
} else {
ForEach(history.indices, id: \.self) { index in
let item = history[index]
VStack(alignment: .leading, spacing: DS.Spacing.xs) {
Text("\(item.submittedTime) · \(item.status)")
.font(.caption)
.foregroundStyle(DS.Color.brandGold)
Text(item.content)
.font(.subheadline)
.foregroundStyle(DS.Color.brandBrown)
}
.padding(DS.Spacing.md)
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.white)
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
}
}
}
}
}