feat: 计划页对齐 android 并新增提交页

This commit is contained in:
AndyChen1024
2026-09-15 14:35:52 +08:00
parent 3e90f8edee
commit 4769aef59e
5 changed files with 564 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
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))
}
}
}
}
}