USB-Meter / USB Meter / Views / Powerbanks / PowerbankEditorSheetView.swift
1 contributor
121 lines | 4.002kb
//
//  PowerbankEditorSheetView.swift
//  USB Meter
//

import SwiftUI

struct PowerbankEditorSheetView: View {
    @EnvironmentObject private var appData: AppData
    @Environment(\.dismiss) private var dismiss

    let powerbank: PowerbankSummary?
    let standalone: Bool

    @State private var name: String
    @State private var batteryLevelReporting: BatteryLevelReporting
    @State private var batteryBarsCount: Int
    @State private var notes: String

    init(
        powerbank: PowerbankSummary? = nil,
        standalone: Bool = true
    ) {
        self.powerbank = powerbank
        self.standalone = standalone
        _name = State(initialValue: powerbank?.name ?? "")
        _batteryLevelReporting = State(initialValue: powerbank?.batteryLevelReporting ?? .percent)
        _batteryBarsCount = State(initialValue: powerbank?.batteryBarsCount ?? 4)
        _notes = State(initialValue: powerbank?.notes ?? "")
    }

    var body: some View {
        ChargedDeviceEditorScaffoldView(
            title: editorTitle,
            saveButtonTitle: saveButtonTitle,
            canSave: canSave,
            standalone: standalone,
            save: save
        ) {
            Section(header: Text("Identity")) {
                TextField("Powerbank name", text: $name)

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

            Section(
                header: ContextInfoHeader(
                    title: "Battery Level Reporting",
                    message: "Powerbanks report battery in different ways: 0–100%, discrete bars (e.g. 4 of 4), a single LED that lights only when full, or not at all. This selection drives how checkpoints are entered and how capacity is learned."
                )
            ) {
                Picker("Reporting", selection: $batteryLevelReporting) {
                    ForEach(BatteryLevelReporting.allCases) { reporting in
                        Text(reporting.title).tag(reporting)
                    }
                }
                .pickerStyle(.menu)

                if batteryLevelReporting == .bars {
                    Stepper(value: $batteryBarsCount, in: 1...10) {
                        Text("Bars resolution: \(batteryBarsCount)")
                    }
                }

                Text(batteryLevelReporting.description)
                    .font(.caption)
                    .foregroundColor(.secondary)
            }

            Section(header: Text("Notes")) {
                TextField("Optional notes", text: $notes)
            }
        }
    }

    private var editorTitle: String {
        powerbank == nil ? "New Powerbank" : "Edit Powerbank"
    }

    private var saveButtonTitle: String {
        powerbank == nil ? "Save" : "Update"
    }

    private var canSave: Bool {
        !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 powerbank {
            didSave = appData.updatePowerbank(
                id: powerbank.id,
                name: name,
                templateID: powerbank.deviceTemplateID,
                batteryLevelReporting: batteryLevelReporting,
                batteryBarsCount: batteryBarsCount,
                notes: notesValue
            )
        } else {
            didSave = appData.createPowerbank(
                name: name,
                templateID: nil,
                batteryLevelReporting: batteryLevelReporting,
                batteryBarsCount: batteryBarsCount,
                notes: notesValue
            )
        }

        if didSave {
            dismiss()
        }
    }
}