05/02 Phase B
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
// Views/Inspection/StartInspectionView.swift
|
||||
// ------------------------------------------
|
||||
// Screen where the inspector chooses a template, facility, and optional area
|
||||
// before starting a new inspection. Creates the LocalInspection record
|
||||
// immediately so the form can be resumed if the app is backgrounded.
|
||||
|
||||
import SwiftUI
|
||||
import SwiftData
|
||||
|
||||
struct StartInspectionView: View {
|
||||
|
||||
@Environment(\.modelContext) private var context
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
@Query(sort: \LocalTemplate.name) private var templates: [LocalTemplate]
|
||||
@Query(sort: \LocalFacility.name) private var facilities: [LocalFacility]
|
||||
|
||||
@State private var selectedTemplateId: Int?
|
||||
@State private var selectedFacilityId: Int?
|
||||
@State private var selectedAreaId: Int?
|
||||
@State private var navigateToExecution = false
|
||||
@State private var createdInspection: LocalInspection?
|
||||
|
||||
@EnvironmentObject private var auth: AuthManager
|
||||
|
||||
private var selectedFacility: LocalFacility? {
|
||||
facilities.first { $0.serverId == selectedFacilityId }
|
||||
}
|
||||
|
||||
private var areas: [LocalArea] {
|
||||
selectedFacility?.areas.sorted { $0.name < $1.name } ?? []
|
||||
}
|
||||
|
||||
private var canStart: Bool {
|
||||
selectedTemplateId != nil && selectedFacilityId != nil
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
// ── Template picker ────────────────────────────────────────
|
||||
Section("Inspection Template") {
|
||||
if templates.isEmpty {
|
||||
Text("No templates available. Sync required.")
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.callout)
|
||||
} else {
|
||||
Picker("Template", selection: $selectedTemplateId) {
|
||||
Text("Select a template…").tag(Optional<Int>(nil))
|
||||
ForEach(templates) { template in
|
||||
VStack(alignment: .leading) {
|
||||
Text(template.name)
|
||||
if !template.frequency.isEmpty {
|
||||
Text(template.frequencyLabel)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
.tag(Optional(template.serverId))
|
||||
}
|
||||
}
|
||||
.pickerStyle(.navigationLink)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Facility picker ────────────────────────────────────────
|
||||
Section("Facility") {
|
||||
if facilities.isEmpty {
|
||||
Text("No facilities available. Sync required.")
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.callout)
|
||||
} else {
|
||||
Picker("Facility", selection: $selectedFacilityId) {
|
||||
Text("Select a facility…").tag(Optional<Int>(nil))
|
||||
ForEach(facilities) { facility in
|
||||
Text(facility.name).tag(Optional(facility.serverId))
|
||||
}
|
||||
}
|
||||
.pickerStyle(.navigationLink)
|
||||
.onChange(of: selectedFacilityId) {
|
||||
selectedAreaId = nil // reset area when facility changes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Area picker (optional) ─────────────────────────────────
|
||||
if selectedFacilityId != nil {
|
||||
Section("Area (Optional)") {
|
||||
Picker("Area", selection: $selectedAreaId) {
|
||||
Text("No specific area").tag(Optional<Int>(nil))
|
||||
ForEach(areas) { area in
|
||||
Text(area.name).tag(Optional(area.serverId))
|
||||
}
|
||||
}
|
||||
.pickerStyle(.navigationLink)
|
||||
.disabled(areas.isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Start button ───────────────────────────────────────────
|
||||
Section {
|
||||
Button {
|
||||
startInspection()
|
||||
} label: {
|
||||
HStack {
|
||||
Spacer()
|
||||
Label("Start Inspection", systemImage: "play.circle.fill")
|
||||
.font(.headline)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.disabled(!canStart)
|
||||
}
|
||||
}
|
||||
.navigationTitle("New Inspection")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button("Cancel") { dismiss() }
|
||||
}
|
||||
}
|
||||
.navigationDestination(isPresented: $navigateToExecution) {
|
||||
if let inspection = createdInspection {
|
||||
ExecuteInspectionView(inspection: inspection)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func startInspection() {
|
||||
guard let templateId = selectedTemplateId,
|
||||
let facilityId = selectedFacilityId
|
||||
else { return }
|
||||
|
||||
let inspection = LocalInspection(
|
||||
templateServerId: templateId,
|
||||
facilityServerId: facilityId,
|
||||
areaServerId: selectedAreaId,
|
||||
inspectorUserId: auth.currentUserId
|
||||
)
|
||||
context.insert(inspection)
|
||||
try? context.save()
|
||||
|
||||
createdInspection = inspection
|
||||
navigateToExecution = true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user