127 lines
3.8 KiB
Swift
127 lines
3.8 KiB
Swift
//
|
|
// SearchScreen.swift
|
|
// AutoCat
|
|
//
|
|
// Created by Selim Mustafaev on 17.02.2025.
|
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
|
//
|
|
|
|
import SwiftUI
|
|
import AutoCatCore
|
|
|
|
struct SearchScreen: View {
|
|
|
|
enum Screen: Hashable {
|
|
|
|
case filter(Filter)
|
|
case map(Filter)
|
|
}
|
|
|
|
@State var viewModel: SearchViewModel
|
|
|
|
init(viewModel: SearchViewModel) {
|
|
|
|
self.viewModel = viewModel
|
|
}
|
|
|
|
var body: some View {
|
|
List(selection: $viewModel.selectedVehicleId) {
|
|
vehicles
|
|
if viewModel.hasMoreData && !viewModel.vehicleSections.isEmpty {
|
|
progressCell
|
|
}
|
|
}
|
|
.listStyle(.plain)
|
|
.hud($viewModel.hud)
|
|
.searchable(text: $viewModel.searchText, prompt: "Search plate numbers")
|
|
.searchPresentationToolbarBehavior(.avoidHidingContent)
|
|
.makeTextFieldDumb()
|
|
.titleModeInline()
|
|
.navigationTitle(String.localizedStringWithFormat(NSLocalizedString("vehicles found", comment: ""),
|
|
viewModel.vehiclesCount))
|
|
.onAppear {
|
|
Task { await viewModel.onAppear() }
|
|
}
|
|
.refreshable {
|
|
Task { await viewModel.reloadData() }
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .primaryAction) {
|
|
toolbarMenu
|
|
}
|
|
}
|
|
.navigationDestination(for: Screen.self) { screen in
|
|
switch screen {
|
|
case .filter(let filter):
|
|
FiltersScreen(filter: filter, onUpdate: viewModel.onFilterChanged)
|
|
case .map(let filter):
|
|
MapScreen(mapInput: .filter(filter))
|
|
}
|
|
}
|
|
.navigationDestination(for: VehicleDto.self) { vehicle in
|
|
return ReportScreen(vehicle: vehicle, isPersistent: false, onUpdate: viewModel.onVehicleChanged)
|
|
}
|
|
}
|
|
|
|
var vehicles: some View {
|
|
ForEach(viewModel.vehicleSections) { section in
|
|
Section(header: Text(section.header)) {
|
|
ForEach(section.elements) { vehicle in
|
|
if Device.isIPhone {
|
|
NavigationLink(value: vehicle) {
|
|
vehicleCell(vehicle)
|
|
}
|
|
} else {
|
|
vehicleCell(vehicle)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func vehicleCell(_ vehicle: VehicleDto) -> some View {
|
|
VehicleCellView(vehicle: vehicle)
|
|
.swipeActions(allowsFullSwipe: false) {
|
|
makeActions(for: vehicle)
|
|
}
|
|
.contextMenu {
|
|
makeActions(for: vehicle, useLabels: true)
|
|
}
|
|
}
|
|
|
|
var progressCell: some View {
|
|
HStack {
|
|
Spacer()
|
|
ProgressView()
|
|
.id(UUID())
|
|
Spacer()
|
|
}
|
|
.onAppear {
|
|
Task { await viewModel.loadMoreData() }
|
|
}
|
|
}
|
|
|
|
var toolbarMenu: some View {
|
|
Menu("", systemImage: "ellipsis") {
|
|
NavigationLink(value: Screen.filter(viewModel.filter)) {
|
|
Label("Filter results", systemImage: "line.horizontal.3.decrease")
|
|
}
|
|
NavigationLink(value: Screen.map(viewModel.filter)) {
|
|
Label("Show on map", systemImage: "map")
|
|
}
|
|
ShareLink(item: viewModel.vehiclesArchive, preview: SharePreview(VehiclesArchive.fileName))
|
|
//ShareLink(items: [viewModel.vehiclesArchive])
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
func makeActions(for vehicle: VehicleDto, useLabels: Bool = false) -> some View {
|
|
|
|
Button {
|
|
Task { await viewModel.updateVehicle(vehicle) }
|
|
} label: {
|
|
Label(useLabels ? "Update" : "", systemImage: "arrow.2.circlepath")
|
|
}
|
|
}
|
|
}
|