252 lines
8.8 KiB
Swift
252 lines
8.8 KiB
Swift
//
|
|
// VehicleDetailView.swift
|
|
// Gas Man
|
|
//
|
|
// Created by Kameron Kenny on 3/18/25.
|
|
//
|
|
import SwiftUI
|
|
|
|
struct VehicleDetailView: View {
|
|
@ObservedObject var vehicle: Vehicle
|
|
@State private var showingEditVehicle = false
|
|
|
|
// Image state for the vehicle photo.
|
|
@State private var vehicleImage: Image? = nil
|
|
@State private var inputImage: UIImage? = nil
|
|
@State private var showImagePicker = false
|
|
@State private var imagePickerSource: UIImagePickerController.SourceType = .photoLibrary
|
|
@State private var showImageSourceOptions = false
|
|
|
|
private let dateFormatter: DateFormatter = {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .short
|
|
return formatter
|
|
}()
|
|
|
|
var body: some View {
|
|
Form {
|
|
// Photo Section at the very top
|
|
Section {
|
|
ZStack {
|
|
if let vehicleImage = vehicleImage {
|
|
vehicleImage
|
|
.resizable()
|
|
.scaledToFill()
|
|
} else {
|
|
Rectangle()
|
|
.fill(Color.gray.opacity(0.2))
|
|
Image(systemName: "camera.fill")
|
|
.font(.largeTitle)
|
|
.foregroundColor(.gray)
|
|
}
|
|
}
|
|
.frame(height: 200)
|
|
.clipped()
|
|
.onTapGesture {
|
|
showImageSourceOptions = true
|
|
}
|
|
.confirmationDialog("Select Photo Source", isPresented: $showImageSourceOptions) {
|
|
if UIImagePickerController.isSourceTypeAvailable(.camera) {
|
|
Button("Camera") {
|
|
imagePickerSource = .camera
|
|
showImagePicker = true
|
|
}
|
|
}
|
|
Button("Photo Library") {
|
|
imagePickerSource = .photoLibrary
|
|
showImagePicker = true
|
|
}
|
|
Button("Cancel", role: .cancel) { }
|
|
}
|
|
.sheet(isPresented: $showImagePicker, onDismiss: loadImage) {
|
|
ImagePicker(sourceType: imagePickerSource, image: $inputImage)
|
|
}
|
|
}
|
|
|
|
// Rest of the details...
|
|
Section(header: Text("Basic Information")) {
|
|
HStack {
|
|
Text("Vehicle Type:")
|
|
Spacer()
|
|
Text(vehicle.vehicleType ?? "")
|
|
}
|
|
HStack {
|
|
Text("Year:")
|
|
Spacer()
|
|
Text(vehicle.year ?? "")
|
|
}
|
|
HStack {
|
|
Text("Make:")
|
|
Spacer()
|
|
Text(vehicle.make ?? "N/A")
|
|
}
|
|
HStack {
|
|
Text("Model:")
|
|
Spacer()
|
|
Text(vehicle.model ?? "N/A")
|
|
}
|
|
HStack {
|
|
Text("Color:")
|
|
Spacer()
|
|
Text(vehicle.color ?? "N/A")
|
|
}
|
|
}
|
|
Section(header: Text("Purchase Information")) {
|
|
HStack {
|
|
Text("Date:")
|
|
Spacer()
|
|
Text(vehicle.purchaseDate != nil ? dateFormatter.string(from: vehicle.purchaseDate!) : "")
|
|
}
|
|
HStack {
|
|
Text("Price:")
|
|
Spacer()
|
|
if let price = vehicle.purchasePrice {
|
|
Text("$\(price.doubleValue, specifier: "%.2f")")
|
|
} else {
|
|
Text("")
|
|
}
|
|
}
|
|
HStack {
|
|
Text("Odometer:")
|
|
Spacer()
|
|
if let odo = vehicle.odometerAtPurchase {
|
|
Text("\(odo.doubleValue, specifier: "%.0f") miles")
|
|
} else {
|
|
Text("")
|
|
}
|
|
}
|
|
}
|
|
Section(header: Text("Engine & Transmission")) {
|
|
HStack {
|
|
Text("Engine Name:")
|
|
Spacer()
|
|
Text(vehicle.engineName ?? "")
|
|
}
|
|
HStack {
|
|
Text("Engine Displacement:")
|
|
Spacer()
|
|
if let ed = vehicle.engineDisplacement {
|
|
Text("\(ed.doubleValue, specifier: "%.3f") L")
|
|
} else {
|
|
Text("")
|
|
}
|
|
}
|
|
HStack {
|
|
Text("Transmission:")
|
|
Spacer()
|
|
Text(vehicle.transmission ?? "Automatic")
|
|
}
|
|
}
|
|
Section(header: Text("Tires")) {
|
|
HStack {
|
|
Text("Brand:")
|
|
Spacer()
|
|
Text(vehicle.tireBrand ?? "")
|
|
}
|
|
HStack {
|
|
Text("Model:")
|
|
Spacer()
|
|
Text(vehicle.tireModel ?? "")
|
|
}
|
|
HStack {
|
|
Text("Size:")
|
|
Spacer()
|
|
if let tw = vehicle.tireSizeWidth {
|
|
Text("\(tw.doubleValue, specifier: "%.0f")")
|
|
} else {
|
|
Text("-")
|
|
}
|
|
Text("/")
|
|
if let th = vehicle.tireSizeHeight {
|
|
Text("\(th.doubleValue, specifier: "%.0f")")
|
|
} else {
|
|
Text("-")
|
|
}
|
|
Text("r")
|
|
if let tr = vehicle.tireSizeRadius {
|
|
Text("\(tr.doubleValue, specifier: "%.0f")")
|
|
} else {
|
|
Text("-")
|
|
}
|
|
}
|
|
}
|
|
Section(header: Text("Wheels")) {
|
|
HStack {
|
|
Text("Brand:")
|
|
Spacer()
|
|
Text(vehicle.wheelBrand ?? "")
|
|
}
|
|
HStack {
|
|
Text("Model:")
|
|
Spacer()
|
|
Text(vehicle.wheelModel ?? "")
|
|
}
|
|
HStack {
|
|
Text("Size:")
|
|
Spacer()
|
|
if let wd = vehicle.wheelSizeDiameter {
|
|
Text("\(wd.doubleValue, specifier: "%.3f")")
|
|
} else {
|
|
Text("-")
|
|
}
|
|
Text(" x ")
|
|
if let ws = vehicle.wheelSizeWidth {
|
|
Text("\(ws.doubleValue, specifier: "%.3f")")
|
|
} else {
|
|
Text("-")
|
|
}
|
|
}
|
|
}
|
|
if vehicle.soldDate != nil {
|
|
Section(header: Text("Sale Information")) {
|
|
HStack {
|
|
Text("Date Sold:")
|
|
Spacer()
|
|
Text(vehicle.soldDate != nil ? dateFormatter.string(from: vehicle.soldDate!) : "")
|
|
}
|
|
HStack {
|
|
Text("Odometer at Sale:")
|
|
Spacer()
|
|
if let odo = vehicle.odometerAtSale {
|
|
Text("\(odo.doubleValue, specifier: "%.0f") miles")
|
|
} else {
|
|
Text("")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Section(header: Text("Notes")) {
|
|
Text(vehicle.notes ?? "")
|
|
}
|
|
}
|
|
.navigationTitle("\(vehicle.make ?? "") \(vehicle.model ?? "")")
|
|
.toolbar {
|
|
ToolbarItem(placement: .navigationBarTrailing) {
|
|
Button("Edit") {
|
|
showingEditVehicle = true
|
|
}
|
|
}
|
|
}
|
|
.sheet(isPresented: $showingEditVehicle) {
|
|
EditVehicleView(vehicle: vehicle)
|
|
.environment(\.managedObjectContext, vehicle.managedObjectContext!)
|
|
}
|
|
.onAppear {
|
|
if let data = vehicle.photo, let uiImage = UIImage(data: data) {
|
|
vehicleImage = Image(uiImage: uiImage)
|
|
}
|
|
}
|
|
}
|
|
|
|
// This function is called when the image picker is dismissed.
|
|
func loadImage() {
|
|
guard let inputImage = inputImage else { return }
|
|
vehicleImage = Image(uiImage: inputImage)
|
|
// Save the image to the vehicle.
|
|
if let imageData = inputImage.jpegData(compressionQuality: 0.8) {
|
|
vehicle.photo = imageData
|
|
try? vehicle.managedObjectContext?.save()
|
|
}
|
|
}
|
|
}
|