USB-Meter / USB Meter / Views / ChargedDevices / ChargerEditorSheetView.swift
1 contributor
117 lines | 3.78kb
//
//  ChargerEditorSheetView.swift
//  USB Meter
//

import SwiftUI

struct ChargerEditorSheetView: View {
    @Environment(\.dismiss) private var dismiss

    let appData: AppData
    let chargedDevice: ChargedDeviceSummary?
    let meterMACAddress: String?
    /// When false the view omits its own NavigationView (used as a push destination).
    let standalone: Bool

    @State private var name: String
    @State private var chargerType: ChargerType
    @State private var notes: String

    init(
        appData: AppData,
        chargedDevice: ChargedDeviceSummary? = nil,
        meterMACAddress: String? = nil,
        standalone: Bool = true
    ) {
        self.appData = appData
        self.chargedDevice = chargedDevice
        self.meterMACAddress = meterMACAddress
        self.standalone = standalone
        _name = State(initialValue: chargedDevice?.name ?? "")
        _chargerType = State(initialValue: chargedDevice?.chargerType ?? .genericQi)
        _notes = State(initialValue: chargedDevice?.notes ?? "")
    }

    var body: some View {
        if standalone {
            NavigationView { formContent }
                .navigationViewStyle(StackNavigationViewStyle())
        } else {
            formContent
        }
    }

    private var formContent: some View {
        Form {
            Section(header: Text("Identity")) {
                TextField("Charger name", text: $name)

                if let chargedDevice {
                    Text(chargedDevice.qrIdentifier)
                        .font(.caption.monospaced())
                        .foregroundColor(.secondary)
                        .textSelection(.enabled)
                }
            }

            Section(
                header: ContextInfoHeader(
                    title: "Charger Type",
                    message: "MagSafe and Watch chargers use magnetic alignment, enabling accurate efficiency calibration. Standby current and efficiency are learned automatically from sessions."
                )
            ) {
                Picker("Type", selection: $chargerType) {
                    ForEach(ChargerType.allCases) { type in
                        Label(type.title, systemImage: type.symbolName)
                            .tag(type)
                    }
                }
                .pickerStyle(.menu)
            }

            Section(header: Text("Notes")) {
                TextField("Optional notes", text: $notes)
            }
        }
        .navigationTitle(chargedDevice == nil ? "New Charger" : "Edit Charger")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .cancellationAction) {
                Button("Cancel") { dismiss() }
            }
            ToolbarItem(placement: .confirmationAction) {
                Button(chargedDevice == nil ? "Save" : "Update") {
                    save()
                }
                .disabled(name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
            }
        }
    }

    private func save() {
        let trimmedNotes = notes.trimmingCharacters(in: .whitespacesAndNewlines)
        let notesValue: String? = trimmedNotes.isEmpty ? nil : trimmedNotes

        let didSave: Bool
        if let chargedDevice {
            didSave = appData.updateCharger(
                id: chargedDevice.id,
                name: name,
                chargerType: chargerType,
                notes: notesValue
            )
        } else {
            didSave = appData.createCharger(
                name: name,
                chargerType: chargerType,
                notes: notesValue,
                meterMACAddress: meterMACAddress
            )
        }

        if didSave {
            dismiss()
        }
    }
}