Files
JQC_iOS_App/JanitorialQC/Views/Dashboard/StartInspectionView.swift
T
2026-05-02 11:46:28 -04:00

148 lines
6.1 KiB
Swift

// 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
}
}