2026-03-20 02:06:19 -05:00
|
|
|
import SwiftUI
|
|
|
|
|
import LabWiseKit
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
2026-03-20 02:06:19 -05:00
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
LabeledContent("Expiration", value: 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)
|
|
|
|
|
}
|
2026-03-20 02:06:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let comments = chemical.comments, !comments.isEmpty {
|
|
|
|
|
Section("Comments") {
|
|
|
|
|
Text(comments)
|
|
|
|
|
.font(.body)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Section("Record") {
|
|
|
|
|
if let created = chemical.createdAt {
|
|
|
|
|
LabeledContent("Created", value: created)
|
|
|
|
|
}
|
|
|
|
|
if let updated = chemical.updatedAt {
|
|
|
|
|
LabeledContent("Updated", value: 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
|
|
|
|
|
}
|
2026-03-20 02:06:19 -05:00
|
|
|
}
|
|
|
|
|
}
|