import SwiftUI struct SettingsView: View { @EnvironmentObject var vm: OrionVMController @State private var selection: UUID? @State private var editing: ServerDefinition? var body: some View { HStack(spacing: 0) { List(selection: $selection) { ForEach(vm.servers) { s in Label(s.name, systemImage: vm.status(for: s).symbolName).tag(s.id) } } .frame(width: 190) Divider() VStack(alignment: .leading, spacing: 14) { if let id = selection, let server = vm.servers.first(where: { $0.id == id }) { Text(server.name).font(.title2).fontWeight(.semibold) LabeledContent("Parallels VM", value: server.vmName); LabeledContent("Host", value: server.host); LabeledContent("SSH user", value: server.sshUser); LabeledContent("SSH port", value: String(server.sshPort)); LabeledContent("SSH key", value: server.sshIdentityFile.isEmpty ? "Default SSH configuration" : server.sshIdentityFile); LabeledContent("Mailpit", value: server.mailpitPort.map(String.init) ?? "Disabled") HStack { Button("Edit…") { editing = server }; Button("Force Stop", role: .destructive) { vm.forceStop(server) }.disabled(vm.status(for: server) == .stopped) } Spacer() } else { ContentUnavailableView("Select a Server", systemImage: "server.rack") } Divider() HStack { Button("Add Server…", systemImage: "plus") { editing = ServerDefinition(name: "New Server", vmName: "", host: "", sshUser: "sysadmin", sshPort: 22, sshIdentityFile: "", mailpitPort: nil) }; Spacer(); Button("Delete", role: .destructive) { if let id = selection, let i = vm.servers.firstIndex(where: {$0.id == id}) { vm.delete(at: IndexSet(integer: i)); selection = nil } }.disabled(selection == nil) } }.padding(20) }.frame(width: 650, height: 380) .sheet(item: $editing) { server in ServerEditor(server: server, isNew: !vm.servers.contains(where: {$0.id == server.id})) { value, isNew in if isNew { vm.add(value) } else { vm.update(value) }; selection = value.id } } } } struct ServerEditor: View { @Environment(\.dismiss) private var dismiss @State var server: ServerDefinition let isNew: Bool let save: (ServerDefinition, Bool) -> Void var body: some View { VStack(alignment: .leading, spacing: 14) { Text(isNew ? "Add Server" : "Edit Server").font(.title2).fontWeight(.semibold) Form { TextField("Display name", text: $server.name) TextField("Parallels VM name", text: $server.vmName) TextField("IP address / host", text: $server.host) TextField("SSH user", text: $server.sshUser) TextField("SSH port", value: $server.sshPort, format: .number) TextField("SSH identity file (optional)", text: $server.sshIdentityFile, prompt: Text("~/.ssh/id_ed25519")) TextField("Mailpit port (optional)", text: Binding(get: { server.mailpitPort.map(String.init) ?? "" }, set: { server.mailpitPort = Int($0) })) } HStack { Spacer(); Button("Cancel") { dismiss() }; Button("Save") { save(server, isNew); dismiss() }.keyboardShortcut(.defaultAction).disabled(server.name.isEmpty || server.vmName.isEmpty || server.host.isEmpty || server.sshUser.isEmpty || server.sshPort < 1 || server.sshPort > 65535) } }.padding(20).frame(width: 470) } }