Jul 13 - Update codes to catch up with the web app updates: scheduled inspection and issue's handler
This commit is contained in:
+113
@@ -0,0 +1,113 @@
|
||||
// Views/Dashboard/ScheduledInspectionsView.swift
|
||||
// ----------------------------------------------
|
||||
// Displays the inspector's planned/recurring inspection assignments (phase36),
|
||||
// pulled read-only from GET /api/v1/scheduled-inspections by
|
||||
// SyncManager.pullScheduledInspections().
|
||||
//
|
||||
// Two consumers share one ScheduledRow:
|
||||
// • ScheduledInspectionsCard — VStack card for the Dashboard ScrollView
|
||||
// • MyInspectionsView renders its own "Scheduled" List section inline,
|
||||
// reusing ScheduledRow, with the start cover attached to the List.
|
||||
// Both self-hide when there are no scheduled inspections and present
|
||||
// StartInspectionView (facility + template preselected) when a row is tapped.
|
||||
// The schedule lifecycle (fulfil / roll-forward) stays server-driven; tapping
|
||||
// "Start" simply seeds the normal new-inspection flow.
|
||||
|
||||
import SwiftUI
|
||||
import SwiftData
|
||||
|
||||
// MARK: - Shared row
|
||||
|
||||
struct ScheduledRow: View {
|
||||
let schedule: LocalScheduledInspection
|
||||
|
||||
private var dueText: String {
|
||||
if let d = schedule.nextDue {
|
||||
return d.formatted(date: .abbreviated, time: .omitted)
|
||||
}
|
||||
return schedule.dueDateString.isEmpty ? "—" : schedule.dueDateString
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .top, spacing: 12) {
|
||||
Image(systemName: "calendar.badge.clock")
|
||||
.font(.title3)
|
||||
.foregroundStyle(schedule.isOverdue ? .red : .blue)
|
||||
.padding(.top, 2)
|
||||
|
||||
VStack(alignment: .leading, spacing: 3) {
|
||||
Text(schedule.templateName.isEmpty ? "Inspection" : schedule.templateName)
|
||||
.font(.callout.bold())
|
||||
Text(schedule.facilityName.isEmpty ? "Facility" : schedule.facilityName)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
if schedule.isOverdue {
|
||||
Text("Overdue")
|
||||
.font(.caption2.bold())
|
||||
.padding(.horizontal, 6).padding(.vertical, 2)
|
||||
.background(Color.red.opacity(0.15))
|
||||
.foregroundStyle(.red)
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
Text("Due \(dueText)")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(schedule.isOverdue ? .red : .secondary)
|
||||
if !schedule.frequencyLabel.isEmpty {
|
||||
Text("· \(schedule.frequencyLabel)")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.tertiary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(minLength: 8)
|
||||
|
||||
Label("Start", systemImage: "play.fill")
|
||||
.font(.caption.bold())
|
||||
.foregroundStyle(.white)
|
||||
.padding(.horizontal, 10).padding(.vertical, 5)
|
||||
.background(schedule.isOverdue ? Color.red : Color.blue)
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Dashboard card (VStack)
|
||||
|
||||
struct ScheduledInspectionsCard: View {
|
||||
@Query(sort: \LocalScheduledInspection.dueDateString, order: .forward)
|
||||
private var scheduled: [LocalScheduledInspection]
|
||||
|
||||
@State private var startTarget: LocalScheduledInspection? = nil
|
||||
|
||||
var body: some View {
|
||||
if !scheduled.isEmpty {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Text("SCHEDULED")
|
||||
.font(.caption.bold())
|
||||
.foregroundStyle(.secondary)
|
||||
.tracking(1)
|
||||
|
||||
ForEach(scheduled) { s in
|
||||
Button { startTarget = s } label: {
|
||||
ScheduledRow(schedule: s)
|
||||
.padding(12)
|
||||
.background(Color(.secondarySystemBackground))
|
||||
.clipShape(RoundedRectangle(cornerRadius: 12))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
// Cover attached to the stable VStack root (mirrors DraftResumeBanner).
|
||||
.fullScreenCover(item: $startTarget) { s in
|
||||
StartInspectionView(
|
||||
preFillTemplateId: s.templateServerId,
|
||||
preFillFacilityId: s.facilityServerId
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user