import PromptGarageCore import SwiftUI struct PromptEditorSheet: View { @Bindable var model: AppModel let presentation: PromptEditorPresentation @State private var draft: PromptDraft init(model: AppModel, presentation: PromptEditorPresentation) { self.model = model self.presentation = presentation _draft = State(initialValue: presentation.initialDraft) } var body: some View { VStack(spacing: 0) { HStack { VStack(alignment: .leading, spacing: 3) { Text(presentation.title) .font(.title2.weight(.semibold)) Text("Wird ausschließlich in deiner lokalen PromptGarage gespeichert.") .font(.caption) .foregroundStyle(.secondary) } Spacer() } .padding(22) .background(.bar) Divider() Form { Section("Prompt") { TextField("Titel", text: $draft.title) TextEditor(text: $draft.content) .font(.body) .frame(minHeight: 230) .scrollContentBackground(.hidden) .padding(8) .background( Color(nsColor: .textBackgroundColor), in: RoundedRectangle(cornerRadius: AppUI.compactCornerRadius) ) .overlay { RoundedRectangle(cornerRadius: AppUI.compactCornerRadius) .stroke(Color(nsColor: .separatorColor).opacity(0.7)) } } Section("Metadaten") { TextField("Tags, durch Kommas getrennt", text: optionalTextBinding(\PromptDraft.tags)) TextField("Quelle", text: $draft.source) TextField("Modell (optional)", text: optionalTextBinding(\PromptDraft.model)) Toggle("Favorit", isOn: $draft.isStarred) LabeledContent("Bewertung") { RatingControl(rating: draft.rating) { draft.rating = $0 } } } if let validationMessage = draft.validationMessage { Section { Label(validationMessage, systemImage: "exclamationmark.circle") .foregroundStyle(.red) } } } .formStyle(.grouped) Divider() HStack { Button("Abbrechen") { model.editor = nil } .keyboardShortcut(.cancelAction) .disabled(model.isSavingEditor) Spacer() Button { Task { _ = await model.saveEditor(draft, presentation: presentation) } } label: { if model.isSavingEditor { HStack(spacing: 8) { ProgressView().controlSize(.small) Text("Speichern …") } } else { Text("Speichern") } } .buttonStyle(.borderedProminent) .keyboardShortcut(.defaultAction) .disabled(draft.validationMessage != nil || model.isSavingEditor) } .padding(16) .background(.bar) } .frame(width: 680, height: 680) .interactiveDismissDisabled(model.isSavingEditor) } private func optionalTextBinding(_ keyPath: WritableKeyPath) -> Binding { Binding( get: { draft[keyPath: keyPath] ?? "" }, set: { draft[keyPath: keyPath] = $0.isEmpty ? nil : $0 } ) } }