Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CoughSync/Models/QuestionnaireType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ import Foundation
enum QuestionnaireType: String {
case profile = "Profile"
case checkIn = "CheckIn"
case morningCheckIn = "MorningCheckIn"
}
87 changes: 87 additions & 0 deletions CoughSync/Resources/MorningCheckInQuestionnaire.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"resourceType": "Questionnaire",
"title": "Morning Check-in",
"id": "morning-checkin",
"name": "MorningCheckIn",
"description": "Daily morning check-in to track your cough symptoms.",
"status": "active",
"subjectType": ["Patient"],
"item": [
{
"linkId": "morning-cough-severity",
"type": "choice",
"text": "How severe was your cough this morning?",
"required": true,
"answerOption": [
{
"valueCoding": {
"code": "1",
"display": "1 - Not severe at all"
}
},
{
"valueCoding": {
"code": "2",
"display": "2 - Slightly severe"
}
},
{
"valueCoding": {
"code": "3",
"display": "3 - Moderately severe"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to check that the language used on this survey so that is standardize across all our surveys

}
},
{
"valueCoding": {
"code": "4",
"display": "4 - Very severe"
}
},
{
"valueCoding": {
"code": "5",
"display": "5 - Extremely severe"
}
}
]
},
{
"linkId": "sleep-quality",
"type": "choice",
"text": "How well did you sleep last night?",
"required": true,
"answerOption": [
{
"valueCoding": {
"code": "1",
"display": "1 - Very poorly"
}
},
{
"valueCoding": {
"code": "2",
"display": "2 - Poorly"
}
},
{
"valueCoding": {
"code": "3",
"display": "3 - Fair"
}
},
{
"valueCoding": {
"code": "4",
"display": "4 - Well"
}
},
{
"valueCoding": {
"code": "5",
"display": "5 - Very well"
}
}
]
}
]
}
10 changes: 10 additions & 0 deletions CoughSync/Schedule/CoughSyncScheduler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ final class CoughSyncScheduler: Module, DefaultInitializable, EnvironmentAccessi
) { context in
context.questionnaire = Bundle.main.questionnaire(withName: "CoughBurdenQuestionnaire")
}

try scheduler.createOrUpdateTask(
id: "morning-checkin",
title: "Morning Check-in",
instructions: "Track your morning symptoms",
category: .questionnaire,
schedule: .daily(hour: 8, minute: 0)
) { context in
context.questionnaire = Bundle.main.questionnaire(withName: "MorningCheckInQuestionnaire")
}
} catch {
viewState = .error(AnyLocalizedError(error: error, defaultErrorDescription: "Failed to create or update scheduled tasks."))
}
Expand Down
8 changes: 7 additions & 1 deletion CoughSync/Schedule/EventView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ struct EventView: View {
}

event.complete()

// Determine questionnaire type based on task ID
let questionnaireType: QuestionnaireType = event.task.id == "morning-checkin"
? .morningCheckIn
: .checkIn

await standard.add(
response: response,
questionnaireType: QuestionnaireType.checkIn
questionnaireType: questionnaireType
)
}
} else {
Expand Down
46 changes: 31 additions & 15 deletions CoughSync/Schedule/ScheduleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,57 @@ import SpeziScheduler
import SpeziSchedulerUI
import SpeziViews
import SwiftUI
import SpeziQuestionnaire


struct ScheduleView: View {
@Environment(Account.self) private var account: Account?
@Environment(CoughSyncScheduler.self) private var scheduler: CoughSyncScheduler
@Environment(CoughSyncStandard.self) private var standard

@State private var presentedEvent: Event?
@Binding private var presentingAccount: Bool


var body: some View {
@Bindable var scheduler = scheduler

NavigationStack {
TodayList { event in
InstructionsTile(event) {
EventActionButton(event: event, "Start Questionnaire") {
presentedEvent = event
List {
// Today's scheduled events
Section {
TodayList { event in
InstructionsTile(event) {
EventActionButton(event: event, "Start Questionnaire") {
presentedEvent = event
}
}
}
}
}
.navigationTitle("Questionnaires")
.viewStateAlert(state: $scheduler.viewState)
.sheet(item: $presentedEvent) { event in
EventView(event)
}
.toolbar {
if account != nil {
AccountButton(isPresented: $presentingAccount)
// Daily Check-ins section
Section(header: Text("Daily Check-ins")) {
ForEach(scheduler.events.filter { $0.task.id == "morning-checkin" }) { event in
InstructionsTile(event) {
EventActionButton(event: event, "Start Check-in") {
presentedEvent = event
}
}
}
}
}
.navigationTitle("Questionnaires")
.viewStateAlert(state: $scheduler.viewState)
.sheet(item: $presentedEvent) { event in
EventView(event)
}
.toolbar {
if account != nil {
AccountButton(isPresented: $presentingAccount)
}
}
}
}


init(presentingAccount: Binding<Bool>) {
self._presentingAccount = presentingAccount
}
Expand Down