import SwiftUI /// `profile set`, or `org profile` for an organization. Description and /// website are single lines; links are capped at five, matching the /// server. The about text is a file and is edited from the profile /// screen, not here. struct ProfileEditSheet: View { let model: ProfileViewModel let profile: ProfileViewModel.Profile @Environment(\.dismiss) private var dismiss @State private var edit: ProfileEdit init(model: ProfileViewModel, profile: ProfileViewModel.Profile) { self.model = model self.profile = profile _edit = State(initialValue: ProfileEdit(from: profile)) } private var localError: String? { edit.validationError } var body: some View { NavigationStack { Form { Section("Description") { TextField("Description", text: $edit.description) .accessibilityIdentifier("profile-edit-description") } Section("Website") { TextField("https://example.com", text: $edit.website) .keyboardType(.URL) .autocorrectionDisabled() .textInputAutocapitalization(.never) .accessibilityIdentifier("profile-edit-website") } linksSection if let error = localError ?? model.actionError { Section { GBNotice(error, .gbWarn) } } } .navigationTitle("Edit Profile") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { dismiss() } } ToolbarItem(placement: .confirmationAction) { if model.working { ProgressView() } else { Button("Save") { save() } .disabled(localError != nil) .accessibilityIdentifier("profile-edit-save") } } } .interactiveDismissDisabled(model.working) } } private var linksSection: some View { Section { ForEach($edit.links) { $link in let index = edit.links.firstIndex { $0.id == link.id } ?? 0 VStack(alignment: .leading, spacing: 4) { TextField("Label", text: $link.label) .autocorrectionDisabled() .accessibilityIdentifier("profile-edit-link-label-\(index)") TextField("https://example.com", text: $link.url) .keyboardType(.URL) .autocorrectionDisabled() .textInputAutocapitalization(.never) .accessibilityIdentifier("profile-edit-link-url-\(index)") } } .onDelete { edit.links.remove(atOffsets: $0) } if edit.links.count < 5 { Button { edit.links.append(.init(label: "", url: "")) } label: { Label("Add Link", systemImage: "plus.circle") } .accessibilityIdentifier("profile-edit-add-link") } } header: { Text("Links") } footer: { Text("Up to 5 links.") } } private func save() { Task { if await model.saveProfile(edit) { dismiss() } } } }