Jul 30 - Update iPad - inspector can re-inspect and create follow-up

This commit is contained in:
Nguyen Ngo
2026-07-30 16:16:15 -04:00
parent b7990cc9ba
commit dac7e6c597
16 changed files with 961 additions and 19 deletions
@@ -24,10 +24,23 @@ struct MyInspectionsView: View {
scheduledAll.filter { !$0.fulfilledLocally }
}
/// Follow-up requests raised on the web rendered as the top section, above
/// Scheduled, and counted in the empty-state decision. Sorted by the flagged
/// inspection's date (ISO strings sort chronologically), oldest first: the
/// longest-outstanding request is the one to clear next.
@Query(sort: \LocalFollowUpRequest.inspectionDateString, order: .forward)
private var followUpsAll: [LocalFollowUpRequest]
/// Rows still awaiting action see FollowUpRequestsCard.visible.
private var followUpsVisible: [LocalFollowUpRequest] {
followUpsAll.filter { !$0.fulfilledLocally }
}
@Environment(\.modelContext) private var context
@State private var showNewInspection = false
@State private var scheduledStartTarget: ScheduledStartTarget?
@State private var followUpStartTarget: FollowUpStartTarget?
// Deletion confirmation state
@State private var pendingDelete: LocalInspection?
@@ -35,7 +48,7 @@ struct MyInspectionsView: View {
var body: some View {
Group {
if inspections.isEmpty && scheduledVisible.isEmpty {
if inspections.isEmpty && scheduledVisible.isEmpty && followUpsVisible.isEmpty {
ContentUnavailableView(
"No Inspections",
systemImage: "checklist",
@@ -43,6 +56,20 @@ struct MyInspectionsView: View {
)
} else {
List {
// Follow-up requests self-hides when empty. First section:
// remedial work on a facility that already failed once
// outranks a routine scheduled visit.
if !followUpsVisible.isEmpty {
Section("Follow-up Requested") {
ForEach(followUpsVisible) { r in
Button { followUpStartTarget = FollowUpStartTarget(r) } label: {
FollowUpRow(request: r)
}
.buttonStyle(.plain)
}
}
}
// Scheduled assignments (phase36) self-hides when empty.
if !scheduledVisible.isEmpty {
Section("Scheduled") {
@@ -87,10 +114,28 @@ struct MyInspectionsView: View {
StartInspectionView(
preFillTemplateId: t.templateServerId,
preFillFacilityId: t.facilityServerId,
// phase45 nil for an ordinary schedule; set when this row is a
// planned follow-up, which makes the run a linked re-inspection.
// Must precede preFillScheduleId: argument order follows the
// property declaration order in StartInspectionView.
parentServerId: t.parentServerId,
preFillScheduleId: t.id,
preFillScheduleInstructions: t.instructions
)
}
// Also on the Group, not the List see the comment above. Submitting the
// last follow-up can flip this view to ContentUnavailableView while the
// cover is still presented. `parentServerId` is what links the run back
// to the flagged inspection; see the twin cover in DashboardStatsView.
.fullScreenCover(item: $followUpStartTarget) { t in
StartInspectionView(
preFillTemplateId: t.templateServerId,
preFillFacilityId: t.facilityServerId,
parentServerId: t.id,
preFillFollowUpNote: t.note,
preFillParentFormDataJSON: t.parentFormDataJSON
)
}
.navigationTitle("My Inspections")
// Confirmation before deletion destructive action cannot be undone
.alert("Delete Draft?", isPresented: $showDeleteAlert, presenting: pendingDelete) { inspection in