Files
LabWiseiOS/LabWise/ChemicalDetailView.swift

161 lines
5.5 KiB
Swift
Raw Permalink Normal View History

import SwiftUI
import LabWiseKit
private let isoDateFormatter: ISO8601DateFormatter = {
let f = ISO8601DateFormatter()
f.formatOptions = [.withFullDate]
return f
}()
private let isoTimestampFormatter: ISO8601DateFormatter = {
let f = ISO8601DateFormatter()
f.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
return f
}()
private let displayDateFormatter: DateFormatter = {
let f = DateFormatter()
f.dateStyle = .medium
f.timeStyle = .none
return f
}()
private let displayTimestampFormatter: DateFormatter = {
let f = DateFormatter()
f.dateStyle = .medium
f.timeStyle = .short
return f
}()
private func formatDate(_ iso: String?) -> String {
guard let iso else { return "" }
if let date = isoDateFormatter.date(from: iso) {
return displayDateFormatter.string(from: date)
}
// Fallback: try full timestamp (e.g. "2025-03-01T00:00:00.000Z")
if let date = isoTimestampFormatter.date(from: iso) {
return displayDateFormatter.string(from: date)
}
return iso
}
private func formatTimestamp(_ iso: String?) -> String {
guard let iso else { return "" }
if let date = isoTimestampFormatter.date(from: iso) {
return displayTimestampFormatter.string(from: date)
}
return iso
}
struct ChemicalDetailView: View {
2026-03-20 02:30:15 -05:00
@State private var chemical: Chemical
@State private var showEdit = false
init(chemical: Chemical) {
self._chemical = State(initialValue: chemical)
}
var body: some View {
Form {
Section("Identity") {
LabeledContent("Name", value: chemical.chemicalName)
LabeledContent("CAS Number", value: chemical.casNumber)
if let formula = chemical.chemicalFormula {
LabeledContent("Formula", value: formula)
}
if let mw = chemical.molecularWeight {
LabeledContent("Molecular Weight", value: mw)
}
LabeledContent("Physical State", value: chemical.physicalState.capitalized)
if let conc = chemical.concentration {
LabeledContent("Concentration", value: conc)
}
}
Section("Storage") {
LabeledContent("Location", value: chemical.storageLocation)
LabeledContent("Device", value: chemical.storageDevice)
LabeledContent("Building", value: chemical.bldgCode)
LabeledContent("Lab", value: chemical.lab)
LabeledContent("Containers", value: chemical.numberOfContainers)
LabeledContent("Amount / Container", value: "\(chemical.amountPerContainer) \(chemical.unitOfMeasure)")
if let pct = chemical.percentageFull {
LabeledContent("% Full") {
HStack(spacing: 8) {
PercentageBar(value: pct / 100)
.frame(width: 80, height: 6)
Text("\(Int(pct))%")
.font(.callout)
}
}
}
}
Section("Vendor") {
LabeledContent("PI", value: chemical.piFirstName)
if let vendor = chemical.vendor {
LabeledContent("Vendor", value: vendor)
}
if let catalog = chemical.catalogNumber {
LabeledContent("Catalog #", value: catalog)
}
if let lot = chemical.lotNumber {
LabeledContent("Lot #", value: lot)
}
if let exp = chemical.expirationDate, !exp.isEmpty {
LabeledContent("Expiration", value: formatDate(exp))
}
if let barcode = chemical.barcode {
LabeledContent("Barcode", value: barcode)
}
2026-03-20 02:30:15 -05:00
if let contact = chemical.contact {
LabeledContent("Contact", value: contact)
}
}
if let comments = chemical.comments, !comments.isEmpty {
Section("Comments") {
Text(comments)
.font(.body)
}
}
Section("Record") {
if let created = chemical.createdAt {
LabeledContent("Created", value: formatTimestamp(created))
}
if let updated = chemical.updatedAt {
LabeledContent("Updated", value: formatTimestamp(updated))
}
}
}
.navigationTitle(chemical.chemicalName)
.navigationBarTitleDisplayMode(.inline)
2026-03-20 02:30:15 -05:00
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
showEdit = true
} label: {
Image(systemName: "pencil")
}
}
}
.sheet(isPresented: $showEdit) {
AddChemicalView(editing: chemical) { saved in
showEdit = false
if saved {
Task { await reloadChemical() }
}
}
}
}
// Reload from server so the detail view reflects the saved changes.
private func reloadChemical() async {
let updated = try? await ChemicalsClient().list()
if let match = updated?.first(where: { $0.id == chemical.id }) {
chemical = match
}
}
}