From dd1deddf4905d123fea2dd10d8c8662011cf0b6b Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Mon, 1 Apr 2024 23:01:25 -0700 Subject: [PATCH] Unify button styles throughout application (#91) # Unify button styles throughout the application ## :recycle: Current situation & Problem Currently, we use a variety of of button styles throughout the application, especially regarding scrolling behavior. ## :gear: Release Notes - Unify button styles throughout the application, especially in regards to scrollable behavior. ## :books: Documentation -- ## :white_check_mark: Testing -- ## :pencil: Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/CS342/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/CS342/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/CS342/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/CS342/.github/blob/main/CONTRIBUTING.md). --- Intake/AllergyView/AllergyRecords.swift | 32 +++++---- Intake/ChiefComplaintView/SummaryView.swift | 17 +++-- Intake/ExportView/ScrollablePDF.swift | 34 +++++---- Intake/Helper/Binding+Negate.swift | 1 + Intake/Helper/Bundle+Image.swift | 1 + .../CodableArray+RawRepresentable.swift | 1 + Intake/Helper/ViewElements.swift | 3 + .../MedicalHistoryView.swift | 25 ++++--- Intake/PatientView/EditPatient.swift | 9 ++- Intake/PatientView/PatientInfo.swift | 69 ++++++++++++------- Intake/Resources/Localizable.xcstrings | 3 + .../SocialHistoryView/MenstrualHistory.swift | 65 +++++++++-------- Intake/SocialHistoryView/SmokingHistory.swift | 35 ++++++---- Intake/SurgeryView/SurgeryView.swift | 27 +++++--- 14 files changed, 208 insertions(+), 114 deletions(-) diff --git a/Intake/AllergyView/AllergyRecords.swift b/Intake/AllergyView/AllergyRecords.swift index 58f2c58..9df7c17 100644 --- a/Intake/AllergyView/AllergyRecords.swift +++ b/Intake/AllergyView/AllergyRecords.swift @@ -49,18 +49,26 @@ struct AllergyList: View { var body: some View { if loaded.allergyData { - VStack { - allergyForm - /**/ - if FeatureFlags.skipToScrollable { - SubmitButton(nextView: NavigationViews.pdfs) - .padding() - } else if data.generalData.sex == "Female" { - SubmitButton(nextView: NavigationViews.menstrual) - .padding() - } else { - SubmitButton(nextView: NavigationViews.smoking) - .padding() + ZStack { + VStack { + allergyForm + + Spacer(minLength: 62) + } + + VStack { + Spacer() + + if FeatureFlags.skipToScrollable { + SubmitButton(nextView: NavigationViews.pdfs) + .padding() + } else if data.generalData.sex == "Female" { + SubmitButton(nextView: NavigationViews.menstrual) + .padding() + } else { + SubmitButton(nextView: NavigationViews.smoking) + .padding() + } } } .sheet(isPresented: $showingChat, content: chatSheetView) diff --git a/Intake/ChiefComplaintView/SummaryView.swift b/Intake/ChiefComplaintView/SummaryView.swift index e437ae3..033ce83 100644 --- a/Intake/ChiefComplaintView/SummaryView.swift +++ b/Intake/ChiefComplaintView/SummaryView.swift @@ -30,10 +30,19 @@ struct SummaryView: View { var body: some View { - VStack(alignment: .leading, spacing: 20) { - ComplaintForm(chiefComplaint: $chiefComplaint) - SubmitButton(nextView: .medical) - .padding() + ZStack { + VStack { + ComplaintForm(chiefComplaint: $chiefComplaint) + + Spacer(minLength: 62) + } + + VStack { + Spacer() + + SubmitButton(nextView: NavigationViews.medical) + .padding() + } } } } diff --git a/Intake/ExportView/ScrollablePDF.swift b/Intake/ExportView/ScrollablePDF.swift index 563861d..0d54f91 100644 --- a/Intake/ExportView/ScrollablePDF.swift +++ b/Intake/ExportView/ScrollablePDF.swift @@ -268,22 +268,30 @@ struct ScrollablePDF: View { var body: some View { - VStack { - Form { - PatientInfo() - ChiefComplaint() - ConditionSection() - SurgerySection() - MedicationSection() - AllergySection() - if data.generalData.sex == "Female" { - MenstrualSection() + ZStack { + VStack { + Form { + PatientInfo() + ChiefComplaint() + ConditionSection() + SurgerySection() + MedicationSection() + AllergySection() + if data.generalData.sex == "Female" { + MenstrualSection() + } + SmokingSection() } - SmokingSection() + + Spacer(minLength: 62) } - ExportButton() - .padding() + VStack { + Spacer() + + ExportButton() + .padding() + } } .navigationTitle("Patient Form") .task { diff --git a/Intake/Helper/Binding+Negate.swift b/Intake/Helper/Binding+Negate.swift index 52fa2af..986454c 100644 --- a/Intake/Helper/Binding+Negate.swift +++ b/Intake/Helper/Binding+Negate.swift @@ -8,6 +8,7 @@ import SwiftUI + extension Binding where Value == Bool { /// Negates a `Binding`. prefix static func ! (value: Binding) -> Binding { diff --git a/Intake/Helper/Bundle+Image.swift b/Intake/Helper/Bundle+Image.swift index 340e2ba..cf3f776 100644 --- a/Intake/Helper/Bundle+Image.swift +++ b/Intake/Helper/Bundle+Image.swift @@ -8,6 +8,7 @@ import SwiftUI + extension Foundation.Bundle { /// Loads an image from the `Bundle` instance. /// - Parameters: diff --git a/Intake/Helper/CodableArray+RawRepresentable.swift b/Intake/Helper/CodableArray+RawRepresentable.swift index 9e0df55..336d010 100644 --- a/Intake/Helper/CodableArray+RawRepresentable.swift +++ b/Intake/Helper/CodableArray+RawRepresentable.swift @@ -8,6 +8,7 @@ import Foundation + extension Array: RawRepresentable where Element: Codable { public var rawValue: String { guard let data = try? JSONEncoder().encode(self), diff --git a/Intake/Helper/ViewElements.swift b/Intake/Helper/ViewElements.swift index b24c49d..797d5a3 100644 --- a/Intake/Helper/ViewElements.swift +++ b/Intake/Helper/ViewElements.swift @@ -7,6 +7,7 @@ import SwiftUI + struct SkipButton: View { var action: () -> Void @@ -27,6 +28,8 @@ struct SubmitButton: View { @Environment(NavigationPathWrapper.self) private var navigationPath @Environment(ReachedEndWrapper.self) private var end var nextView: NavigationViews + + var body: some View { Button(action: { if end.reachedEnd { diff --git a/Intake/MedicalHistoryView/MedicalHistoryView.swift b/Intake/MedicalHistoryView/MedicalHistoryView.swift index 9b786a5..ecdf665 100644 --- a/Intake/MedicalHistoryView/MedicalHistoryView.swift +++ b/Intake/MedicalHistoryView/MedicalHistoryView.swift @@ -28,14 +28,23 @@ struct MedicalHistoryView: View { var body: some View { if loaded.conditionData { - VStack { - medicalHistoryForm - if FeatureFlags.testCondition { - SubmitButton(nextView: NavigationViews.pdfs) - .padding() - } else { - SubmitButton(nextView: NavigationViews.surgical) - .padding() + ZStack { + VStack { + medicalHistoryForm + + Spacer(minLength: 62) + } + + VStack { + Spacer() + + if FeatureFlags.testCondition { + SubmitButton(nextView: NavigationViews.pdfs) + .padding() + } else { + SubmitButton(nextView: NavigationViews.surgical) + .padding() + } } } .sheet(isPresented: $showingChat, content: chatSheetView) diff --git a/Intake/PatientView/EditPatient.swift b/Intake/PatientView/EditPatient.swift index 56564aa..4f7b9a4 100644 --- a/Intake/PatientView/EditPatient.swift +++ b/Intake/PatientView/EditPatient.swift @@ -19,7 +19,7 @@ struct EditPatientView: View { var body: some View { @Bindable var data = data - VStack { + ZStack { Form { Section(header: Text("Name")) { TextField("Name", text: $data.generalData.name) @@ -35,7 +35,12 @@ struct EditPatientView: View { } } - SubmitButton(nextView: NavigationViews.pdfs) + VStack { + Spacer() + + SubmitButton(nextView: NavigationViews.pdfs) + .padding() + } } } } diff --git a/Intake/PatientView/PatientInfo.swift b/Intake/PatientView/PatientInfo.swift index 3a49b88..fc17a03 100644 --- a/Intake/PatientView/PatientInfo.swift +++ b/Intake/PatientView/PatientInfo.swift @@ -19,40 +19,47 @@ struct PatientInfo: View { @State private var birthdateDateFormat = Date() @Environment(DataStore.self) private var data - @Environment(NavigationPathWrapper.self) private var navigationPath @Environment(FHIRStore.self) private var fhirStore var body: some View { @Bindable var data = data - VStack { - Form { - Section(header: Text("Patient Information")) { - TextField(text: $data.generalData.name) { - Text("Full name") - } - - DatePicker("Date of Birth:", selection: $birthdateDateFormat, in: ...Date(), displayedComponents: .date) - .datePickerStyle(DefaultDatePickerStyle()) - - Picker("Sex", selection: $sexOption) { - ForEach(["Female", "Male"], id: \.self) { option in - Text(option).tag(option) + ZStack { + VStack { + Form { + Section(header: Text("Patient Information")) { + TextField(text: $data.generalData.name) { + Text("Full name") + } + + DatePicker("Date of Birth:", selection: $birthdateDateFormat, in: ...Date(), displayedComponents: .date) + .datePickerStyle(DefaultDatePickerStyle()) + + Picker("Sex", selection: $sexOption) { + ForEach(["Female", "Male"], id: \.self) { option in + Text(option).tag(option) + } } - } .pickerStyle(MenuPickerStyle()) + } } + + Spacer(minLength: 62) + } + + VStack { + Spacer() + + SubmitButtonWithAction( + nextView: FeatureFlags.skipToScrollable ? .pdfs : .chat, + onButtonTap: { + updateData() + }, + accessibilityIdentifier: "Next" + ) + .padding() } - - SubmitButtonWithAction( - nextView: FeatureFlags.skipToScrollable ? .pdfs : .chat, - onButtonTap: { - updateData() - }, - accessibilityIdentifier: "Next" - ) - .padding() } .task { loadData() @@ -162,8 +169,18 @@ extension String { } -struct PatientInfo_Previews: PreviewProvider { - static var previews: some View { +#Preview { + @State var dataStore = DataStore() + @State var fhirStore = FHIRStore() + @State var navigationPath = NavigationPathWrapper() + @State var reachedEnd = ReachedEndWrapper() + + + return NavigationStack { PatientInfo() } + .environment(dataStore) + .environment(fhirStore) + .environment(navigationPath) + .environment(reachedEnd) } diff --git a/Intake/Resources/Localizable.xcstrings b/Intake/Resources/Localizable.xcstrings index 1bc5bc4..9fa7d25 100644 --- a/Intake/Resources/Localizable.xcstrings +++ b/Intake/Resources/Localizable.xcstrings @@ -147,6 +147,9 @@ }, "Back" : { + }, + "Chat with LLM Assistant" : { + }, "Chief Complaint:" : { diff --git a/Intake/SocialHistoryView/MenstrualHistory.swift b/Intake/SocialHistoryView/MenstrualHistory.swift index e5dde28..183b5d9 100644 --- a/Intake/SocialHistoryView/MenstrualHistory.swift +++ b/Intake/SocialHistoryView/MenstrualHistory.swift @@ -21,40 +21,49 @@ struct SocialHistoryQuestionView: View { var body: some View { - VStack { - if data.generalData.sex == "Female" { - Form { - Section(header: Text("Menstrual Information").foregroundColor(.gray)) { - @Bindable var data = data - DatePicker("Last period's start date", selection: $startDate, in: ...Date(), displayedComponents: .date) - .datePickerStyle(DefaultDatePickerStyle()) + if data.generalData.sex == "Female" { + ZStack { + VStack { + Form { + Section(header: Text("Menstrual Information").foregroundColor(.gray)) { + @Bindable var data = data + DatePicker("Last period's start date", selection: $startDate, in: ...Date(), displayedComponents: .date) + .datePickerStyle(DefaultDatePickerStyle()) + + DatePicker("Last period's end date", selection: $endDate, in: ...Date(), displayedComponents: .date) + .datePickerStyle(DefaultDatePickerStyle()) + } - DatePicker("Last period's end date", selection: $endDate, in: ...Date(), displayedComponents: .date) - .datePickerStyle(DefaultDatePickerStyle()) + Section(header: Text("Additional Symptoms").foregroundColor(.gray)) { + @Bindable var data = data + TextField("Ex: Heavy bleeding on second day, fatigue...", text: $additionalDetails) + } } - Section(header: Text("Additional Symptoms").foregroundColor(.gray)) { - @Bindable var data = data - TextField("Ex: Heavy bleeding on second day, fatigue...", text: $additionalDetails) - } - } - .navigationTitle("Menstrual History") - .task { - startDate = data.menstrualHistory.startDate - endDate = data.menstrualHistory.endDate - additionalDetails = data.menstrualHistory.additionalDetails + Spacer(minLength: 62) } - .onDisappear { - data.menstrualHistory = MenstrualHistoryItem(startDate: startDate, endDate: endDate, additionalDetails: additionalDetails) - } - if FeatureFlags.skipToScrollable { - SubmitButton(nextView: NavigationViews.pdfs) - .padding() - } else { - SubmitButton(nextView: NavigationViews.smoking) - .padding() + + VStack { + Spacer() + + if FeatureFlags.skipToScrollable { + SubmitButton(nextView: NavigationViews.pdfs) + .padding() + } else { + SubmitButton(nextView: NavigationViews.smoking) + .padding() + } } } + .navigationTitle("Menstrual History") + .task { + startDate = data.menstrualHistory.startDate + endDate = data.menstrualHistory.endDate + additionalDetails = data.menstrualHistory.additionalDetails + } + .onDisappear { + data.menstrualHistory = MenstrualHistoryItem(startDate: startDate, endDate: endDate, additionalDetails: additionalDetails) + } } } } diff --git a/Intake/SocialHistoryView/SmokingHistory.swift b/Intake/SocialHistoryView/SmokingHistory.swift index 00330f5..75496f4 100644 --- a/Intake/SocialHistoryView/SmokingHistory.swift +++ b/Intake/SocialHistoryView/SmokingHistory.swift @@ -18,21 +18,30 @@ struct SmokingHistoryView: View { var body: some View { - VStack { - Form { - initialSmokingQuestionSection - - if hasSmokedOrSmoking { - followUpQuestionsSection - additionalDetailsSection + ZStack { + VStack { + Form { + initialSmokingQuestionSection + + if hasSmokedOrSmoking { + followUpQuestionsSection + additionalDetailsSection + } } + + Spacer(minLength: 62) } - if FeatureFlags.skipToScrollable { - SubmitButton(nextView: NavigationViews.pdfs) - .padding() - } else { - SubmitButton(nextView: NavigationViews.pdfs) - .padding() + + VStack { + Spacer() + + if FeatureFlags.skipToScrollable { + SubmitButton(nextView: NavigationViews.pdfs) + .padding() + } else { + SubmitButton(nextView: NavigationViews.pdfs) + .padding() + } } } .navigationTitle("Social History") diff --git a/Intake/SurgeryView/SurgeryView.swift b/Intake/SurgeryView/SurgeryView.swift index c950395..81bc0e3 100644 --- a/Intake/SurgeryView/SurgeryView.swift +++ b/Intake/SurgeryView/SurgeryView.swift @@ -91,14 +91,23 @@ struct SurgeryView: View { var body: some View { @Bindable var data = data if data.surgeriesLoaded { - VStack { - surgeryForm - if FeatureFlags.skipToScrollable { - SubmitButton(nextView: NavigationViews.pdfs) - .padding() - } else { - SubmitButton(nextView: NavigationViews.medication) - .padding() + ZStack { + VStack { + surgeryForm + + Spacer(minLength: 62) + } + + VStack { + Spacer() + + if FeatureFlags.skipToScrollable { + SubmitButton(nextView: NavigationViews.pdfs) + .padding() + } else { + SubmitButton(nextView: NavigationViews.medication) + .padding() + } } } .navigationTitle("Surgical History") @@ -121,6 +130,7 @@ struct SurgeryView: View { private var surgeryElements: some View { Group { @Bindable var data = data + ForEach($data.surgeries) { $item in NavigationLink(destination: InspectSurgeryView(surgery: $item, isNew: false)) { Label(item.surgeryName, systemImage: "arrowtriangle.right") @@ -134,6 +144,7 @@ struct SurgeryView: View { private var surgeryForm: some View { Form { @Bindable var data = data + Section(header: Text("Please add your past surgeries")) { if data.surgeries.isEmpty { Text("Select + to add a surgery")