From efec14139cd5d39ed37aeecd4ae1688a5c945829 Mon Sep 17 00:00:00 2001 From: pulipakaa24 Date: Fri, 20 Mar 2026 02:05:53 -0500 Subject: [PATCH] UI updates for labwise branding --- LabWise.xcodeproj/project.pbxproj | 14 +- .../BrandDestructive.colorset/Contents.json | 20 ++ .../BrandMuted.colorset/Contents.json | 20 ++ .../Contents.json | 20 ++ .../BrandPrimary.colorset/Contents.json | 20 ++ .../BrandSecondary.colorset/Contents.json | 20 ++ .../GoogleLogo.imageset/Contents.json | 15 ++ .../GoogleLogo.imageset/google-logo.svg | 6 + .../Logo.imageset/Contents.json | 21 ++ .../Assets.xcassets/Logo.imageset/logo.png | Bin 0 -> 76655 bytes LabWise/ContentView.swift | 24 --- LabWise/DashboardView.swift | 22 ++ LabWise/LoginView.swift | 200 ++++++++++++++++++ LabWiseKit/.gitignore | 8 + LabWiseKit/Package.swift | 26 +++ .../Sources/LabWiseKit/LabWiseKit.swift | 2 + .../Sources/LabWiseKit/Models/Chemical.swift | 164 ++++++++++++++ .../LabWiseKit/Models/LabProtocol.swift | 83 ++++++++ .../LabWiseKitTests/LabWiseKitTests.swift | 6 + LabWiseUITests/LabWiseKit/.gitignore | 8 + LabWiseUITests/LabWiseKit/Package.swift | 26 +++ .../Sources/LabWiseKit/LabWiseKit.swift | 2 + .../LabWiseKitTests/LabWiseKitTests.swift | 6 + 23 files changed, 705 insertions(+), 28 deletions(-) create mode 100644 LabWise/Assets.xcassets/BrandDestructive.colorset/Contents.json create mode 100644 LabWise/Assets.xcassets/BrandMuted.colorset/Contents.json create mode 100644 LabWise/Assets.xcassets/BrandMutedForeground.colorset/Contents.json create mode 100644 LabWise/Assets.xcassets/BrandPrimary.colorset/Contents.json create mode 100644 LabWise/Assets.xcassets/BrandSecondary.colorset/Contents.json create mode 100644 LabWise/Assets.xcassets/GoogleLogo.imageset/Contents.json create mode 100644 LabWise/Assets.xcassets/GoogleLogo.imageset/google-logo.svg create mode 100644 LabWise/Assets.xcassets/Logo.imageset/Contents.json create mode 100644 LabWise/Assets.xcassets/Logo.imageset/logo.png delete mode 100644 LabWise/ContentView.swift create mode 100644 LabWise/DashboardView.swift create mode 100644 LabWise/LoginView.swift create mode 100644 LabWiseKit/.gitignore create mode 100644 LabWiseKit/Package.swift create mode 100644 LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift create mode 100644 LabWiseKit/Sources/LabWiseKit/Models/Chemical.swift create mode 100644 LabWiseKit/Sources/LabWiseKit/Models/LabProtocol.swift create mode 100644 LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift create mode 100644 LabWiseUITests/LabWiseKit/.gitignore create mode 100644 LabWiseUITests/LabWiseKit/Package.swift create mode 100644 LabWiseUITests/LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift create mode 100644 LabWiseUITests/LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift diff --git a/LabWise.xcodeproj/project.pbxproj b/LabWise.xcodeproj/project.pbxproj index 67ff70e..ca868d2 100644 --- a/LabWise.xcodeproj/project.pbxproj +++ b/LabWise.xcodeproj/project.pbxproj @@ -400,11 +400,14 @@ DEVELOPMENT_TEAM = YK2DB9NT3S; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; + INFOPLIST_KEY_NSCameraUsageDescription = "Camera Access needed for scanning chemical labels for adding to inventory."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -432,11 +435,14 @@ DEVELOPMENT_TEAM = YK2DB9NT3S; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; + INFOPLIST_KEY_NSCameraUsageDescription = "Camera Access needed for scanning chemical labels for adding to inventory."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/LabWise/Assets.xcassets/BrandDestructive.colorset/Contents.json b/LabWise/Assets.xcassets/BrandDestructive.colorset/Contents.json new file mode 100644 index 0000000..dd52cab --- /dev/null +++ b/LabWise/Assets.xcassets/BrandDestructive.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x3D", + "green" : "0x18", + "red" : "0xD4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LabWise/Assets.xcassets/BrandMuted.colorset/Contents.json b/LabWise/Assets.xcassets/BrandMuted.colorset/Contents.json new file mode 100644 index 0000000..5022054 --- /dev/null +++ b/LabWise/Assets.xcassets/BrandMuted.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF3", + "green" : "0xF5", + "red" : "0xF0" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LabWise/Assets.xcassets/BrandMutedForeground.colorset/Contents.json b/LabWise/Assets.xcassets/BrandMutedForeground.colorset/Contents.json new file mode 100644 index 0000000..975b724 --- /dev/null +++ b/LabWise/Assets.xcassets/BrandMutedForeground.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x6F", + "green" : "0x7A", + "red" : "0x5A" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LabWise/Assets.xcassets/BrandPrimary.colorset/Contents.json b/LabWise/Assets.xcassets/BrandPrimary.colorset/Contents.json new file mode 100644 index 0000000..7409fad --- /dev/null +++ b/LabWise/Assets.xcassets/BrandPrimary.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x4A", + "green" : "0x5A", + "red" : "0x2D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LabWise/Assets.xcassets/BrandSecondary.colorset/Contents.json b/LabWise/Assets.xcassets/BrandSecondary.colorset/Contents.json new file mode 100644 index 0000000..70b9aad --- /dev/null +++ b/LabWise/Assets.xcassets/BrandSecondary.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF0", + "green" : "0xF3", + "red" : "0xE8" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LabWise/Assets.xcassets/GoogleLogo.imageset/Contents.json b/LabWise/Assets.xcassets/GoogleLogo.imageset/Contents.json new file mode 100644 index 0000000..c6508ba --- /dev/null +++ b/LabWise/Assets.xcassets/GoogleLogo.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "google-logo.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/LabWise/Assets.xcassets/GoogleLogo.imageset/google-logo.svg b/LabWise/Assets.xcassets/GoogleLogo.imageset/google-logo.svg new file mode 100644 index 0000000..a771b22 --- /dev/null +++ b/LabWise/Assets.xcassets/GoogleLogo.imageset/google-logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/LabWise/Assets.xcassets/Logo.imageset/Contents.json b/LabWise/Assets.xcassets/Logo.imageset/Contents.json new file mode 100644 index 0000000..5f670ca --- /dev/null +++ b/LabWise/Assets.xcassets/Logo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "logo.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LabWise/Assets.xcassets/Logo.imageset/logo.png b/LabWise/Assets.xcassets/Logo.imageset/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a6b0969b6de65bf8f14c855c781f3a372f7b956f GIT binary patch literal 76655 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 YbRh>%(h5XQkbgmwky4Z_5!d(oKf*l9R{#J2 literal 0 HcmV?d00001 diff --git a/LabWise/ContentView.swift b/LabWise/ContentView.swift deleted file mode 100644 index 8dca6af..0000000 --- a/LabWise/ContentView.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ContentView.swift -// LabWise -// -// Created by Aditya Pulipaka on 3/19/26. -// - -import SwiftUI - -struct ContentView: View { - var body: some View { - VStack { - Image(systemName: "globe") - .imageScale(.large) - .foregroundStyle(.tint) - Text("Hello, world!") - } - .padding() - } -} - -#Preview { - ContentView() -} diff --git a/LabWise/DashboardView.swift b/LabWise/DashboardView.swift new file mode 100644 index 0000000..11641bd --- /dev/null +++ b/LabWise/DashboardView.swift @@ -0,0 +1,22 @@ +import SwiftUI + +struct DashboardView: View { + var body: some View { + TabView { + Tab("Chemicals", systemImage: "flask.fill") { + ChemicalsListView() + } + Tab("Scan", systemImage: "camera.fill") { + ScanView() + } + Tab("Profile", systemImage: "person.fill") { + ProfileView() + } + } + .tint(Color("Brand/BrandPrimary")) + } +} + +#Preview { + DashboardView() +} diff --git a/LabWise/LoginView.swift b/LabWise/LoginView.swift new file mode 100644 index 0000000..b800b36 --- /dev/null +++ b/LabWise/LoginView.swift @@ -0,0 +1,200 @@ +import SwiftUI +import AuthenticationServices +import LabWiseKit + +struct LoginView: View { + @Environment(AppState.self) private var appState + + @State private var email = "" + @State private var password = "" + @State private var isLoading = false + @State private var isGoogleLoading = false + @State private var errorMessage: String? + + private let authClient = AuthClient() + + var body: some View { + NavigationStack { + ZStack { + Color(UIColor.systemGroupedBackground) + .ignoresSafeArea() + + VStack(spacing: 32) { + Spacer() + + // Logo + VStack(spacing: 16) { + Image("Logo") + .resizable() + .scaledToFit() + .frame(height: 52) + Text("Chemical Inventory Management") + .font(.subheadline) + .foregroundStyle(Color("Brand/BrandMutedForeground")) + } + + // Card + VStack(spacing: 20) { + VStack(spacing: 12) { + TextField("Email", text: $email) + .keyboardType(.emailAddress) + .textContentType(.emailAddress) + .autocapitalization(.none) + .padding(.horizontal, 12) + .padding(.vertical, 10) + .background(Color(UIColor.secondarySystemGroupedBackground)) + .clipShape(RoundedRectangle(cornerRadius: 10)) + .overlay( + RoundedRectangle(cornerRadius: 10) + .strokeBorder(Color("Brand/BrandPrimary").opacity(0.2), lineWidth: 1) + ) + + SecureField("Password", text: $password) + .textContentType(.password) + .padding(.horizontal, 12) + .padding(.vertical, 10) + .background(Color(UIColor.secondarySystemGroupedBackground)) + .clipShape(RoundedRectangle(cornerRadius: 10)) + .overlay( + RoundedRectangle(cornerRadius: 10) + .strokeBorder(Color("Brand/BrandPrimary").opacity(0.2), lineWidth: 1) + ) + } + + if let errorMessage { + Text(errorMessage) + .foregroundStyle(.red) + .font(.footnote) + .multilineTextAlignment(.center) + } + + Button { + Task { await signIn() } + } label: { + Group { + if isLoading { + ProgressView() + .tint(.white) + } else { + Text("Sign In") + .fontWeight(.semibold) + } + } + .frame(maxWidth: .infinity) + .frame(height: 44) + } + .background(Color("Brand/BrandPrimary")) + .foregroundStyle(.white) + .clipShape(RoundedRectangle(cornerRadius: 10)) + .disabled(email.isEmpty || password.isEmpty || isLoading || isGoogleLoading) + .opacity((email.isEmpty || password.isEmpty || isLoading || isGoogleLoading) ? 0.5 : 1) + + HStack { + Rectangle() + .fill(Color("Brand/BrandPrimary").opacity(0.15)) + .frame(height: 1) + Text("or") + .font(.footnote) + .foregroundStyle(Color("Brand/BrandMutedForeground")) + Rectangle() + .fill(Color("Brand/BrandPrimary").opacity(0.15)) + .frame(height: 1) + } + + GoogleSignInButton(isLoading: isGoogleLoading) { + Task { await signInWithGoogle() } + } + .disabled(isLoading || isGoogleLoading) + } + .padding(24) + .background(Color(UIColor.secondarySystemGroupedBackground)) + .clipShape(RoundedRectangle(cornerRadius: 16)) + .shadow(color: Color("Brand/BrandPrimary").opacity(0.06), radius: 12, x: 0, y: 4) + .padding(.horizontal, 24) + + Spacer() + } + } + .navigationBarHidden(true) + } + } + + // MARK: - Actions + + private func signIn() async { + isLoading = true + errorMessage = nil + defer { isLoading = false } + + do { + let user = try await authClient.signIn(email: email, password: password) + await MainActor.run { appState.signedIn(user: user) } + } catch APIError.httpError(let code, _) where code == 401 { + await MainActor.run { errorMessage = "Invalid email or password." } + } catch APIError.httpError(_, let data) { + let msg = String(data: data, encoding: .utf8) ?? "Sign in failed." + await MainActor.run { errorMessage = msg } + } catch { + await MainActor.run { errorMessage = "Sign in failed. Please check your connection." } + } + } + + @MainActor + private func signInWithGoogle() async { + guard let window = UIApplication.shared.connectedScenes + .compactMap({ $0 as? UIWindowScene }) + .flatMap({ $0.windows }) + .first(where: { $0.isKeyWindow }) else { return } + + isGoogleLoading = true + errorMessage = nil + defer { isGoogleLoading = false } + + do { + let user = try await authClient.signInWithGoogle(presentingWindow: window) + appState.signedIn(user: user) + } catch ASWebAuthenticationSessionError.canceledLogin { + // User cancelled — no error shown + } catch { + errorMessage = "Google sign-in failed. Please try again." + } + } +} + +// MARK: - Google button + +struct GoogleSignInButton: View { + let isLoading: Bool + let action: () -> Void + + var body: some View { + Button(action: action) { + HStack(spacing: 10) { + if isLoading { + ProgressView() + .frame(maxWidth: .infinity) + } else { + Image(systemName: "globe") + .foregroundStyle(Color("Brand/BrandPrimary")) + Text("Continue with Google") + .fontWeight(.medium) + .foregroundStyle(Color(UIColor.label)) + } + } + .frame(maxWidth: .infinity) + .frame(height: 44) + .background(Color(UIColor.systemBackground)) + .clipShape(RoundedRectangle(cornerRadius: 10)) + .overlay( + RoundedRectangle(cornerRadius: 10) + .strokeBorder(Color("Brand/BrandPrimary").opacity(0.25), lineWidth: 1) + ) + } + .buttonStyle(.plain) + } +} + +#Preview { + LoginView() + .environment(AppState.shared) +} diff --git a/LabWiseKit/.gitignore b/LabWiseKit/.gitignore new file mode 100644 index 0000000..0023a53 --- /dev/null +++ b/LabWiseKit/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/LabWiseKit/Package.swift b/LabWiseKit/Package.swift new file mode 100644 index 0000000..4b7928f --- /dev/null +++ b/LabWiseKit/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 6.2 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "LabWiseKit", + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "LabWiseKit", + targets: ["LabWiseKit"] + ), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "LabWiseKit" + ), + .testTarget( + name: "LabWiseKitTests", + dependencies: ["LabWiseKit"] + ), + ] +) diff --git a/LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift b/LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift new file mode 100644 index 0000000..08b22b8 --- /dev/null +++ b/LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift @@ -0,0 +1,2 @@ +// The Swift Programming Language +// https://docs.swift.org/swift-book diff --git a/LabWiseKit/Sources/LabWiseKit/Models/Chemical.swift b/LabWiseKit/Sources/LabWiseKit/Models/Chemical.swift new file mode 100644 index 0000000..f239168 --- /dev/null +++ b/LabWiseKit/Sources/LabWiseKit/Models/Chemical.swift @@ -0,0 +1,164 @@ +import Foundation + +public struct Chemical: Codable, Identifiable, Sendable { + public let id: String + // Required + public var piFirstName: String + public var physicalState: String + public var chemicalName: String + public var bldgCode: String + public var lab: String + public var storageLocation: String + public var storageDevice: String + public var numberOfContainers: String + public var amountPerContainer: String + public var unitOfMeasure: String + public var casNumber: String + // Optional + public var chemicalFormula: String? + public var molecularWeight: String? + public var vendor: String? + public var catalogNumber: String? + public var lotNumber: String? + public var expirationDate: String? + public var concentration: String? + public var percentageFull: Double? + public var comments: String? + public var barcode: String? + public var contact: String? + public var scannedImage: String? + public var needsManualEntry: [String]? + public var createdAt: String? + public var updatedAt: String? + + public init( + id: String = "", + piFirstName: String = "", + physicalState: String = "", + chemicalName: String = "", + bldgCode: String = "", + lab: String = "", + storageLocation: String = "", + storageDevice: String = "", + numberOfContainers: String = "", + amountPerContainer: String = "", + unitOfMeasure: String = "", + casNumber: String = "", + chemicalFormula: String? = nil, + molecularWeight: String? = nil, + vendor: String? = nil, + catalogNumber: String? = nil, + lotNumber: String? = nil, + expirationDate: String? = nil, + concentration: String? = nil, + percentageFull: Double? = nil, + comments: String? = nil, + barcode: String? = nil, + contact: String? = nil, + scannedImage: String? = nil, + needsManualEntry: [String]? = nil, + createdAt: String? = nil, + updatedAt: String? = nil + ) { + self.id = id + self.piFirstName = piFirstName + self.physicalState = physicalState + self.chemicalName = chemicalName + self.bldgCode = bldgCode + self.lab = lab + self.storageLocation = storageLocation + self.storageDevice = storageDevice + self.numberOfContainers = numberOfContainers + self.amountPerContainer = amountPerContainer + self.unitOfMeasure = unitOfMeasure + self.casNumber = casNumber + self.chemicalFormula = chemicalFormula + self.molecularWeight = molecularWeight + self.vendor = vendor + self.catalogNumber = catalogNumber + self.lotNumber = lotNumber + self.expirationDate = expirationDate + self.concentration = concentration + self.percentageFull = percentageFull + self.comments = comments + self.barcode = barcode + self.contact = contact + self.scannedImage = scannedImage + self.needsManualEntry = needsManualEntry + self.createdAt = createdAt + self.updatedAt = updatedAt + } +} + +public struct ChemicalCreateBody: Codable, Sendable { + public var piFirstName: String + public var physicalState: String + public var chemicalName: String + public var bldgCode: String + public var lab: String + public var storageLocation: String + public var storageDevice: String + public var numberOfContainers: String + public var amountPerContainer: String + public var unitOfMeasure: String + public var casNumber: String + public var chemicalFormula: String? + public var molecularWeight: String? + public var vendor: String? + public var catalogNumber: String? + public var lotNumber: String? + public var expirationDate: String? + public var concentration: String? + public var percentageFull: Double? + public var comments: String? + public var barcode: String? + public var contact: String? + + public init( + piFirstName: String, + physicalState: String, + chemicalName: String, + bldgCode: String, + lab: String, + storageLocation: String, + storageDevice: String, + numberOfContainers: String, + amountPerContainer: String, + unitOfMeasure: String, + casNumber: String, + chemicalFormula: String? = nil, + molecularWeight: String? = nil, + vendor: String? = nil, + catalogNumber: String? = nil, + lotNumber: String? = nil, + expirationDate: String? = nil, + concentration: String? = nil, + percentageFull: Double? = nil, + comments: String? = nil, + barcode: String? = nil, + contact: String? = nil + ) { + self.piFirstName = piFirstName + self.physicalState = physicalState + self.chemicalName = chemicalName + self.bldgCode = bldgCode + self.lab = lab + self.storageLocation = storageLocation + self.storageDevice = storageDevice + self.numberOfContainers = numberOfContainers + self.amountPerContainer = amountPerContainer + self.unitOfMeasure = unitOfMeasure + self.casNumber = casNumber + self.chemicalFormula = chemicalFormula + self.molecularWeight = molecularWeight + self.vendor = vendor + self.catalogNumber = catalogNumber + self.lotNumber = lotNumber + self.expirationDate = expirationDate + self.concentration = concentration + self.percentageFull = percentageFull + self.comments = comments + self.barcode = barcode + self.contact = contact + } +} diff --git a/LabWiseKit/Sources/LabWiseKit/Models/LabProtocol.swift b/LabWiseKit/Sources/LabWiseKit/Models/LabProtocol.swift new file mode 100644 index 0000000..fb166e2 --- /dev/null +++ b/LabWiseKit/Sources/LabWiseKit/Models/LabProtocol.swift @@ -0,0 +1,83 @@ +import Foundation + +/// A lab protocol document. Named `LabProtocol` to avoid collision with the Swift keyword `Protocol`. +public struct LabProtocol: Codable, Identifiable, Sendable { + public let id: String + public var title: String + public var content: String + public var fileUrl: String? + public var analysisResults: AnyCodable? + public var createdAt: String? + public var updatedAt: String? + + enum CodingKeys: String, CodingKey { + case id, title, content, fileUrl, analysisResults, createdAt, updatedAt + } + + public init( + id: String = "", + title: String = "", + content: String = "", + fileUrl: String? = nil, + analysisResults: AnyCodable? = nil, + createdAt: String? = nil, + updatedAt: String? = nil + ) { + self.id = id + self.title = title + self.content = content + self.fileUrl = fileUrl + self.analysisResults = analysisResults + self.createdAt = createdAt + self.updatedAt = updatedAt + } +} + +// MARK: - AnyCodable helper + +public struct AnyCodable: Codable, Sendable { + public let value: any Sendable + + public init(_ value: any Sendable) { + self.value = value + } + + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + if let intVal = try? container.decode(Int.self) { + value = intVal + } else if let doubleVal = try? container.decode(Double.self) { + value = doubleVal + } else if let boolVal = try? container.decode(Bool.self) { + value = boolVal + } else if let stringVal = try? container.decode(String.self) { + value = stringVal + } else if let arrayVal = try? container.decode([AnyCodable].self) { + value = arrayVal + } else if let dictVal = try? container.decode([String: AnyCodable].self) { + value = dictVal + } else { + value = NSNull() + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + switch value { + case let intVal as Int: + try container.encode(intVal) + case let doubleVal as Double: + try container.encode(doubleVal) + case let boolVal as Bool: + try container.encode(boolVal) + case let stringVal as String: + try container.encode(stringVal) + case let arrayVal as [AnyCodable]: + try container.encode(arrayVal) + case let dictVal as [String: AnyCodable]: + try container.encode(dictVal) + default: + try container.encodeNil() + } + } +} diff --git a/LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift b/LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift new file mode 100644 index 0000000..3e960a2 --- /dev/null +++ b/LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift @@ -0,0 +1,6 @@ +import Testing +@testable import LabWiseKit + +@Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. +} diff --git a/LabWiseUITests/LabWiseKit/.gitignore b/LabWiseUITests/LabWiseKit/.gitignore new file mode 100644 index 0000000..0023a53 --- /dev/null +++ b/LabWiseUITests/LabWiseKit/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/LabWiseUITests/LabWiseKit/Package.swift b/LabWiseUITests/LabWiseKit/Package.swift new file mode 100644 index 0000000..4b7928f --- /dev/null +++ b/LabWiseUITests/LabWiseKit/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 6.2 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "LabWiseKit", + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "LabWiseKit", + targets: ["LabWiseKit"] + ), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "LabWiseKit" + ), + .testTarget( + name: "LabWiseKitTests", + dependencies: ["LabWiseKit"] + ), + ] +) diff --git a/LabWiseUITests/LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift b/LabWiseUITests/LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift new file mode 100644 index 0000000..08b22b8 --- /dev/null +++ b/LabWiseUITests/LabWiseKit/Sources/LabWiseKit/LabWiseKit.swift @@ -0,0 +1,2 @@ +// The Swift Programming Language +// https://docs.swift.org/swift-book diff --git a/LabWiseUITests/LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift b/LabWiseUITests/LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift new file mode 100644 index 0000000..3e960a2 --- /dev/null +++ b/LabWiseUITests/LabWiseKit/Tests/LabWiseKitTests/LabWiseKitTests.swift @@ -0,0 +1,6 @@ +import Testing +@testable import LabWiseKit + +@Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. +}