@hedia/recommendation-screen 1.0.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/android/app/src/main/res/values/color.xml +3 -0
  2. package/android/app/src/main/res/values/styles.xml +3 -0
  3. package/index.ts +3 -16
  4. package/ios/HediaRecommendationScreen/Info.plist +80 -57
  5. package/ios/HediaRecommendationScreen.xcodeproj/project.pbxproj +1085 -807
  6. package/ios/HediaRecommendationScreen.xcworkspace/contents.xcworkspacedata +10 -0
  7. package/ios/HediaRecommendationScreen.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  8. package/ios/Podfile +106 -104
  9. package/ios/Podfile.lock +474 -0
  10. package/jest.mock.js +1 -0
  11. package/package.json +9 -2
  12. package/src/RecommendationScreen.tsx +130 -60
  13. package/src/assets/activity/Cyclist.png +0 -0
  14. package/src/assets/activity/Other.png +0 -0
  15. package/src/assets/activity/Runner.png +0 -0
  16. package/src/assets/activity/Swimmer.png +0 -0
  17. package/src/assets/activity/Walk.png +0 -0
  18. package/src/components/Header.tsx +7 -14
  19. package/src/components/HediaRecommendationModal.tsx +231 -0
  20. package/src/components/InfoBars.tsx +3 -3
  21. package/src/components/InvisibleNumberInput.tsx +7 -7
  22. package/src/components/RecentInsulin.tsx +6 -5
  23. package/src/components/RecommendedCarbs.tsx +24 -24
  24. package/src/components/RecommendedInsulin.tsx +18 -15
  25. package/src/components/Remeasure.tsx +15 -13
  26. package/src/components/TransferToLogbook.tsx +6 -4
  27. package/src/components/activity/Activity.tsx +74 -0
  28. package/src/components/activity/ActivityIcon.tsx +52 -0
  29. package/src/components/activity/ActivityIntensity.tsx +66 -0
  30. package/src/components/mood/Emotion.tsx +64 -0
  31. package/src/components/{MoodIcon.tsx → mood/MoodIcon.tsx} +17 -17
  32. package/src/locale/da/messages.js +1 -1
  33. package/src/locale/da/messages.po +191 -49
  34. package/src/locale/en/messages.js +1 -1
  35. package/src/locale/en/messages.po +193 -51
  36. package/src/types/enum.ts +48 -3
  37. package/src/types/types.ts +21 -1
  38. package/src/utils/AttentionMessages.ts +59 -0
  39. package/src/utils/Constants.ts +20 -1
  40. package/src/utils/RecommendationError.ts +114 -28
  41. package/src/utils/RecommendationUtils.ts +128 -0
  42. package/src/utils/Utils.ts +13 -5
  43. package/src/utils/Validations.ts +210 -0
  44. package/App.jsx +0 -70
  45. package/index.d.ts +0 -5
  46. package/index.js +0 -16
  47. package/src/RecommendationScreen.d.ts +0 -43
  48. package/src/RecommendationScreen.jsx +0 -158
  49. package/src/components/Emotion.d.ts +0 -14
  50. package/src/components/Emotion.jsx +0 -54
  51. package/src/components/Emotion.tsx +0 -70
  52. package/src/components/Header.d.ts +0 -52
  53. package/src/components/Header.jsx +0 -82
  54. package/src/components/InfoBars.d.ts +0 -67
  55. package/src/components/InfoBars.jsx +0 -90
  56. package/src/components/InvisibleNumberInput.d.ts +0 -24
  57. package/src/components/InvisibleNumberInput.jsx +0 -64
  58. package/src/components/MoodIcon.d.ts +0 -14
  59. package/src/components/MoodIcon.jsx +0 -53
  60. package/src/components/RecentInsulin.d.ts +0 -9
  61. package/src/components/RecentInsulin.jsx +0 -90
  62. package/src/components/RecommendedCarbs.d.ts +0 -30
  63. package/src/components/RecommendedCarbs.jsx +0 -193
  64. package/src/components/RecommendedInsulin.d.ts +0 -22
  65. package/src/components/RecommendedInsulin.jsx +0 -109
  66. package/src/components/Remeasure.d.ts +0 -13
  67. package/src/components/Remeasure.jsx +0 -88
  68. package/src/components/TransferToLogbook.d.ts +0 -14
  69. package/src/components/TransferToLogbook.jsx +0 -80
  70. package/src/locale/i18nUtils.d.ts +0 -5
  71. package/src/locale/i18nUtils.js +0 -22
  72. package/src/types/enum.d.ts +0 -34
  73. package/src/types/enum.js +0 -43
  74. package/src/types/types.d.ts +0 -21
  75. package/src/types/types.js +0 -2
  76. package/src/utils/Constants.d.ts +0 -3
  77. package/src/utils/Constants.js +0 -6
  78. package/src/utils/RecommendationError.d.ts +0 -11
  79. package/src/utils/RecommendationError.js +0 -18
  80. package/src/utils/Utils.d.ts +0 -5
  81. package/src/utils/Utils.js +0 -24
  82. /package/src/assets/{happy.png → mood/happy.png} +0 -0
  83. /package/src/assets/{happy_active.png → mood/happy_active.png} +0 -0
  84. /package/src/assets/{neutral.png → mood/neutral.png} +0 -0
  85. /package/src/assets/{neutral_active.png → mood/neutral_active.png} +0 -0
  86. /package/src/assets/{sad.png → mood/sad.png} +0 -0
  87. /package/src/assets/{sad_active.png → mood/sad_active.png} +0 -0
  88. /package/src/assets/{semi_happy.png → mood/semi_happy.png} +0 -0
  89. /package/src/assets/{semi_happy_active.png → mood/semi_happy_active.png} +0 -0
  90. /package/src/assets/{semi_sad.png → mood/semi_sad.png} +0 -0
  91. /package/src/assets/{semi_sad_active.png → mood/semi_sad_active.png} +0 -0
@@ -0,0 +1,128 @@
1
+ import { IRecommendationParams } from "@hedia/recommendation-calculator";
2
+ import moment from "moment";
3
+ import { IRecommendationProps } from "../RecommendationScreen";
4
+ import { BgLevel, RecommendationReminders } from "../types/enum";
5
+ import { IActivity, logbookEntry } from "../types/types";
6
+ import { addPostponeActivityMessage, AttentionMessage, Messages } from "./AttentionMessages";
7
+ import { SEVERE_HYPERGLYCEMIA_START_MMOL } from "./Constants";
8
+ import { CurrentBGLError } from "./RecommendationError";
9
+
10
+ export function getBGLevel(currentBGL: number, latestLogbookFrom6Hours: logbookEntry): BgLevel {
11
+ if (currentBGL === null) {
12
+ return BgLevel.BGLevelNotProvided;
13
+ }
14
+ if (currentBGL >= 1.1 && currentBGL <= 2) {
15
+ return BgLevel.SevereHypoglycemia;
16
+ }
17
+ if (currentBGL > 2 && currentBGL <= 3.5) {
18
+ return BgLevel.Hypoglycemia;
19
+ }
20
+ if (currentBGL > 3.5 && currentBGL <= 4) {
21
+ return BgLevel.MildHypoglycemia;
22
+ }
23
+ if (currentBGL > 4 && currentBGL < 5) {
24
+ return BgLevel.NormoglycemiaUnder5MMOL;
25
+ }
26
+ if (currentBGL >= 5 && currentBGL <= 7) {
27
+ return BgLevel.Normoglycemia;
28
+ }
29
+ if (currentBGL > 7 && currentBGL < 15) {
30
+ return BgLevel.MildHyperglycemia;
31
+ }
32
+ if (currentBGL > 15 && currentBGL <= 33.3 && isSevereHyperglycemia(latestLogbookFrom6Hours)) {
33
+ return BgLevel.SevereHyperglycemia;
34
+ }
35
+ if (currentBGL >= 15 && currentBGL <= 33.3) {
36
+ return BgLevel.Hyperglycemia;
37
+ }
38
+ return BgLevel.UnsupportedBGLevel;
39
+ }
40
+
41
+ export function getReminder(
42
+ bgLevel: BgLevel,
43
+ carbohydrates: number,
44
+ userReminder: number,
45
+ activity: IRecommendationParams["activity"],
46
+ ): number {
47
+ const reminder = userReminder === undefined ? RecommendationReminders.HediaReminderDefault : userReminder;
48
+ switch (bgLevel) {
49
+ case BgLevel.BGLevelNotProvided:
50
+ return RecommendationReminders.ReminderOff;
51
+
52
+ case BgLevel.SevereHypoglycemia:
53
+ case BgLevel.Hypoglycemia:
54
+ case BgLevel.MildHypoglycemia:
55
+ return RecommendationReminders.Reminder15Minutes;
56
+
57
+ case BgLevel.NormoglycemiaUnder5MMOL:
58
+ case BgLevel.Normoglycemia:
59
+ case BgLevel.MildHyperglycemia:
60
+ return carbohydrates || activity ? reminder : RecommendationReminders.ReminderOff;
61
+
62
+ case BgLevel.Hyperglycemia:
63
+ case BgLevel.SevereHyperglycemia:
64
+ return isActivityWithin15Minutes(activity)
65
+ ? RecommendationReminders.Reminder15Minutes
66
+ : RecommendationReminders.Reminder60Minutes;
67
+
68
+ default:
69
+ throw CurrentBGLError();
70
+ }
71
+ }
72
+
73
+ export function getAttentionMessage(bgLevel: BgLevel, activity: IRecommendationParams["activity"]): AttentionMessage {
74
+ switch (bgLevel) {
75
+ case BgLevel.BGLevelNotProvided:
76
+ case BgLevel.Normoglycemia:
77
+ case BgLevel.MildHyperglycemia:
78
+ return undefined;
79
+
80
+ case BgLevel.NormoglycemiaUnder5MMOL:
81
+ return isActivityWithin15Minutes(activity) ? AttentionMessage.NormoglycemiaActivityUnder5MMOL() : undefined;
82
+
83
+ case BgLevel.SevereHypoglycemia:
84
+ case BgLevel.Hypoglycemia:
85
+ case BgLevel.MildHypoglycemia:
86
+ return isActivityWithin15Minutes(activity)
87
+ ? addPostponeActivityMessage(AttentionMessage[BgLevel[bgLevel]]())
88
+ : AttentionMessage[BgLevel[bgLevel]]();
89
+
90
+ case BgLevel.Hyperglycemia:
91
+ return isActivityWithin15Minutes(activity) ? AttentionMessage.HyperglycemiaActivity() : undefined;
92
+
93
+ case BgLevel.SevereHyperglycemia:
94
+ return isActivityWithin15Minutes(activity)
95
+ ? AttentionMessage.SevereHyperglycemiaActivity()
96
+ : AttentionMessage.SevereHyperglycemia();
97
+ default:
98
+ throw CurrentBGLError();
99
+ }
100
+ }
101
+
102
+ export function isSevereHyperglycemia(latestLogbookFrom6Hours: logbookEntry): boolean {
103
+ return latestLogbookFrom6Hours?.blood_glucose_millimolar > SEVERE_HYPERGLYCEMIA_START_MMOL;
104
+ }
105
+
106
+ export function isActivityWithin15Minutes(activity: IRecommendationParams["activity"]): boolean {
107
+ const minutes = activity?.activityDuration;
108
+ return moment
109
+ .utc(activity?.activityDate)
110
+ .isBetween(moment.utc().subtract(minutes, `minutes`), moment.utc().add(15, `minutes`));
111
+ }
112
+
113
+ export function getLimitationMessage(wasLimited: boolean, activityReduction: number): Messages {
114
+ const message = activityReduction
115
+ ? Messages.RecommendationWasLimitedActivity(activityReduction)
116
+ : Messages.RecommendationWasLimited();
117
+ return wasLimited ? message : undefined;
118
+ }
119
+
120
+ export function getParams(props: IRecommendationProps): IRecommendationParams & IActivity {
121
+ const { calculatorParams } = props;
122
+ const activityTarget = calculatorParams.activity?.activitySettings?.target;
123
+ const paramsWithAssignedCurrentBGL = {
124
+ ...calculatorParams,
125
+ currentBGL: activityTarget ?? calculatorParams.targetBGL,
126
+ };
127
+ return calculatorParams.currentBGL === null ? paramsWithAssignedCurrentBGL : calculatorParams;
128
+ }
@@ -1,7 +1,8 @@
1
1
  import { InjectionMethod } from "../types/enum";
2
+ import { IInterval } from "../types/types";
2
3
 
3
4
  export class Utils {
4
- public static getRounding(method: InjectionMethod) {
5
+ public static getRounding(method: InjectionMethod): number {
5
6
  switch (method) {
6
7
  case InjectionMethod.PenWhole:
7
8
  return 1;
@@ -17,10 +18,17 @@ export class Utils {
17
18
  }
18
19
  }
19
20
 
20
- public static roundValue(value: number, injectMethod: InjectionMethod) {
21
- const rounding = Utils.getRounding(injectMethod);
22
-
23
- const rounded = Math.round(value * rounding) / rounding;
21
+ public static roundValue(value: number, injectMethod: InjectionMethod): number {
22
+ const rounding: number = Utils.getRounding(injectMethod);
23
+ const rounded: number = Math.round(value * rounding) / rounding;
24
24
  return rounded;
25
25
  }
26
+
27
+ public static isInClosedInterval(value: number, interval: IInterval): boolean {
28
+ if (value === null) {
29
+ return false;
30
+ }
31
+
32
+ return value >= interval.min && value <= interval.max;
33
+ }
26
34
  }
@@ -0,0 +1,210 @@
1
+ import { IRecommendationParams } from "@hedia/recommendation-calculator";
2
+ import {
3
+ ActivityIntensity,
4
+ IActivityInterval,
5
+ IActivitySettings,
6
+ IRecentBolus,
7
+ } from "@hedia/recommendation-calculator/src/RecommendationCalculator";
8
+ import moment from "moment";
9
+ import { IRecommendationProps } from "../RecommendationScreen";
10
+ import { ActivityInterval, BGUnit, InjectionMethod, Languages } from "../types/enum";
11
+ import {
12
+ ACTIVITY_DURATION_MINUTES_LIMITS,
13
+ ACTIVITY_SETTINGS_INTERVAL_LIMITS,
14
+ ACTIVITY_TARGET_BGL_MMOL_LIMITS,
15
+ BOLUS_SECONDS_PASSED_LIMITS,
16
+ CARBOHYDRATES_LIMTS,
17
+ CURRENT_BGL_MMOL_LIMITS,
18
+ INSULIN_DOSIS_LIMITS,
19
+ INSULIN_SENSITIVITY_MMOL_LIMITS,
20
+ INSULIN_TO_CARBS_RATIO_LIMITS,
21
+ ONE_HOUR_MINUTES,
22
+ REMINDER_HOURS_LIMITS,
23
+ TARGET_BGL_MMOL_LIMITS,
24
+ } from "./Constants";
25
+ import {
26
+ ActivityDateError,
27
+ ActivityDurationError,
28
+ ActivityIntensityError,
29
+ ActivitySettingsError,
30
+ ActivityTargetBGLError,
31
+ BolusInsulinDosisError,
32
+ BolusInsulinSecondsPassedError,
33
+ CarbohydrateLimitError,
34
+ CurrentBGLError,
35
+ InjectionMethodError,
36
+ InsulinSensitivityError,
37
+ InsulinToCarbsRatioError,
38
+ LanguageError,
39
+ TargetBGLError,
40
+ UnitError,
41
+ UserReminderError,
42
+ } from "./RecommendationError";
43
+ import { Utils } from "./Utils";
44
+
45
+ export function validateParams(props: IRecommendationProps): void {
46
+ checkCalculatorParams(props.calculatorParams);
47
+ checkUnit(props.units);
48
+ checkInjectionMethod(props.injectionMethod);
49
+ checkUserReminder(props.userReminder);
50
+ checkLanguage(props.language);
51
+ }
52
+
53
+ export function checkLanguage(language: Languages): void {
54
+ switch (language) {
55
+ case Languages.da:
56
+ case Languages.en:
57
+ break;
58
+ default:
59
+ throw LanguageError();
60
+ }
61
+ }
62
+
63
+ export function checkInjectionMethod(injectionMethod: InjectionMethod): void {
64
+ switch (injectionMethod) {
65
+ case InjectionMethod.PenHalf:
66
+ case InjectionMethod.PenWhole:
67
+ case InjectionMethod.Pump:
68
+ break;
69
+ default:
70
+ throw InjectionMethodError();
71
+ }
72
+ }
73
+
74
+ export function checkUnit(unit: BGUnit): void {
75
+ switch (unit) {
76
+ case BGUnit.MG_DL:
77
+ case BGUnit.MMOL_L:
78
+ break;
79
+ default:
80
+ throw UnitError();
81
+ }
82
+ }
83
+
84
+ export function checkUserReminder(userReminder: number): void {
85
+ if (!Utils.isInClosedInterval(userReminder, REMINDER_HOURS_LIMITS)) {
86
+ throw UserReminderError();
87
+ }
88
+ }
89
+
90
+ function checkCalculatorParams(calculatorParams: IRecommendationProps["calculatorParams"]): void {
91
+ checkActivity(calculatorParams.activity);
92
+ checkCarbohydrates(calculatorParams.carbohydrates);
93
+ checkCurrentBGL(calculatorParams.currentBGL);
94
+ checkTargetBGL(calculatorParams.targetBGL);
95
+ checkInsulinToCarbRatio(calculatorParams.carbohydrateRatio);
96
+ checkInsulinSensitivity(calculatorParams.insulinSensitivity);
97
+ checkRecentBolusesInsulinDosis(calculatorParams.recentBoluses);
98
+ checkRecentBolusesSecondsPassed(calculatorParams.recentBoluses);
99
+ }
100
+
101
+ export function checkActivity(activity: IRecommendationParams["activity"]): void {
102
+ if (activity) {
103
+ checkActivityDate(activity);
104
+ checkActivityDuration(activity.activityDuration);
105
+ checkActivityIntensity(activity.activityIntensity);
106
+ checkActivitySettings(activity.activitySettings);
107
+ checkActivityTargetBGL(activity.activitySettings.target);
108
+ }
109
+ }
110
+
111
+ export function checkRecentBolusesInsulinDosis(recentBoluses: Array<IRecentBolus>): void {
112
+ recentBoluses.forEach((bolus: IRecentBolus): void => {
113
+ if (!Utils.isInClosedInterval(bolus.insulinDosis, INSULIN_DOSIS_LIMITS)) {
114
+ throw BolusInsulinDosisError();
115
+ }
116
+ });
117
+ }
118
+
119
+ export function checkRecentBolusesSecondsPassed(recentBoluses: Array<IRecentBolus>): void {
120
+ recentBoluses.forEach((bolus: IRecentBolus): void => {
121
+ if (!Utils.isInClosedInterval(bolus.secondsPassed, BOLUS_SECONDS_PASSED_LIMITS)) {
122
+ throw BolusInsulinSecondsPassedError();
123
+ }
124
+ });
125
+ }
126
+
127
+ export function checkActivityDuration(activityDuration: IRecommendationParams["activity"]["activityDuration"]): void {
128
+ if (!Utils.isInClosedInterval(activityDuration, ACTIVITY_DURATION_MINUTES_LIMITS)) {
129
+ throw ActivityDurationError();
130
+ }
131
+ }
132
+
133
+ export function checkActivityIntensity(
134
+ activityIntensity: IRecommendationParams["activity"]["activityIntensity"],
135
+ ): void {
136
+ switch (activityIntensity) {
137
+ case ActivityIntensity.Hard:
138
+ case ActivityIntensity.Moderate:
139
+ case ActivityIntensity.Light:
140
+ case ActivityIntensity.Post:
141
+ break;
142
+ default:
143
+ throw ActivityIntensityError();
144
+ }
145
+ }
146
+ export function checkActivityDate(activity: IRecommendationParams["activity"]): void {
147
+ const maximumDate = moment
148
+ .utc(activity.activityDate)
149
+ .add(activity.activityDuration + ONE_HOUR_MINUTES * 4, `minutes`);
150
+ if (!moment.utc().isBefore(maximumDate)) {
151
+ throw ActivityDateError();
152
+ }
153
+ }
154
+
155
+ type intensityType = Omit<IActivitySettings, "target">;
156
+ export function checkActivitySettings(activitySettings: IRecommendationParams["activity"]["activitySettings"]): void {
157
+ for (const intensity of Object.keys(activitySettings) as Array<keyof intensityType>) {
158
+ for (const interval of Object.keys(activitySettings[intensity]) as Array<keyof IActivityInterval>) {
159
+ const value: number = activitySettings[intensity][interval];
160
+ const isInInterval: boolean = Utils.isInClosedInterval(value, ACTIVITY_SETTINGS_INTERVAL_LIMITS);
161
+ if (intensity === ActivityIntensity.Hard.toLowerCase() && interval === ActivityInterval.fromFortysix) {
162
+ if (!isInInterval && value !== null) {
163
+ throw ActivitySettingsError();
164
+ }
165
+ } else if (!isInInterval) {
166
+ throw ActivitySettingsError();
167
+ }
168
+ }
169
+ }
170
+ }
171
+
172
+ export function checkActivityTargetBGL(
173
+ activitySettings: IRecommendationParams["activity"]["activitySettings"]["target"],
174
+ ): void {
175
+ if (!Utils.isInClosedInterval(activitySettings, ACTIVITY_TARGET_BGL_MMOL_LIMITS)) {
176
+ throw ActivityTargetBGLError();
177
+ }
178
+ }
179
+
180
+ export function checkCurrentBGL(currentBGL: number): void {
181
+ if (currentBGL !== null) {
182
+ if (!Utils.isInClosedInterval(currentBGL, CURRENT_BGL_MMOL_LIMITS)) {
183
+ throw CurrentBGLError();
184
+ }
185
+ }
186
+ }
187
+
188
+ export function checkTargetBGL(targetBGL: number): void {
189
+ if (!Utils.isInClosedInterval(targetBGL, TARGET_BGL_MMOL_LIMITS)) {
190
+ throw TargetBGLError();
191
+ }
192
+ }
193
+
194
+ export function checkInsulinSensitivity(insulinSensitivity: number): void {
195
+ if (!Utils.isInClosedInterval(insulinSensitivity, INSULIN_SENSITIVITY_MMOL_LIMITS)) {
196
+ throw InsulinSensitivityError();
197
+ }
198
+ }
199
+
200
+ export function checkInsulinToCarbRatio(insulinToCarbRatio: number): void {
201
+ if (!Utils.isInClosedInterval(insulinToCarbRatio, INSULIN_TO_CARBS_RATIO_LIMITS)) {
202
+ throw InsulinToCarbsRatioError();
203
+ }
204
+ }
205
+
206
+ export function checkCarbohydrates(carbohydrates: number): void {
207
+ if (!Utils.isInClosedInterval(carbohydrates, CARBOHYDRATES_LIMTS)) {
208
+ throw CarbohydrateLimitError();
209
+ }
210
+ }
package/App.jsx DELETED
@@ -1,70 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const react_1 = __importDefault(require("react"));
7
- const RecommendationScreen_1 = __importDefault(require("./src/RecommendationScreen"));
8
- const enum_1 = require("./src/types/enum");
9
- class App extends react_1.default.Component {
10
- constructor(props) {
11
- super(props);
12
- this.exitCallback = () => {
13
- console.log(`Exiting...`);
14
- };
15
- this.removeCarbs = () => {
16
- this.setState({
17
- carbs: null,
18
- });
19
- };
20
- this.changeCarbs = (carbs) => {
21
- this.setState({
22
- carbs,
23
- });
24
- };
25
- this.onYes = () => {
26
- console.log(`Navigate to recent bolus screen`);
27
- };
28
- this.updatedRecommendedInsulin = (val) => {
29
- console.log(`Updated recommended insulin: `, val);
30
- };
31
- this.transferToLogbook = (...params) => {
32
- console.log(`Transfered:`, params);
33
- };
34
- this.handleError = (error) => {
35
- console.log(JSON.stringify(error));
36
- switch (error.type) {
37
- case enum_1.RecommendationErrorEnum.ActivityOutOfRange:
38
- console.log(`Handling activity out of range!`);
39
- break;
40
- default:
41
- throw error;
42
- }
43
- };
44
- const params = {
45
- carbohydrateRatio: 10,
46
- carbohydrates: 4,
47
- currentBGL: 2.2,
48
- insulinSensitivity: 4,
49
- targetBGL: 6,
50
- recentBoluses: [],
51
- };
52
- const paramsTest = {
53
- currentBGL: 10.8,
54
- carbohydrates: 27,
55
- carbohydrateRatio: 22,
56
- insulinSensitivity: 5,
57
- targetBGL: 7,
58
- recentBoluses: [],
59
- };
60
- this.state = {
61
- params,
62
- carbs: 25,
63
- injectionMethod: enum_1.InjectionMethod.Pump,
64
- };
65
- }
66
- render() {
67
- return (<RecommendationScreen_1.default language={enum_1.Languages.en} injectionMethod={this.state.injectionMethod} calculatorParams={this.state.params} units={enum_1.BGUnit.MMOL_L} exitCallback={this.exitCallback} removeRecommendedCarbs={this.removeCarbs} onRecentInsulinYes={this.onYes} transferToLogbook={this.transferToLogbook} onError={this.handleError}/>);
68
- }
69
- }
70
- exports.default = App;
package/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import RecommendationScreen from "./src/RecommendationScreen";
2
- import { RecommendationErrorEnum } from "./src/types/enum";
3
- import { ActivityNullError, ActivityRangeError, CarbohydrateLimitError, InsulinLimitError, RecommendationError } from "./src/utils/RecommendationError";
4
- export default RecommendationScreen;
5
- export { ActivityNullError, ActivityRangeError, CarbohydrateLimitError, InsulinLimitError, RecommendationError, RecommendationErrorEnum, };
package/index.js DELETED
@@ -1,16 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.RecommendationErrorEnum = exports.RecommendationError = exports.InsulinLimitError = exports.CarbohydrateLimitError = exports.ActivityRangeError = exports.ActivityNullError = void 0;
7
- const RecommendationScreen_1 = __importDefault(require("./src/RecommendationScreen"));
8
- const enum_1 = require("./src/types/enum");
9
- Object.defineProperty(exports, "RecommendationErrorEnum", { enumerable: true, get: function () { return enum_1.RecommendationErrorEnum; } });
10
- const RecommendationError_1 = require("./src/utils/RecommendationError");
11
- Object.defineProperty(exports, "ActivityNullError", { enumerable: true, get: function () { return RecommendationError_1.ActivityNullError; } });
12
- Object.defineProperty(exports, "ActivityRangeError", { enumerable: true, get: function () { return RecommendationError_1.ActivityRangeError; } });
13
- Object.defineProperty(exports, "CarbohydrateLimitError", { enumerable: true, get: function () { return RecommendationError_1.CarbohydrateLimitError; } });
14
- Object.defineProperty(exports, "InsulinLimitError", { enumerable: true, get: function () { return RecommendationError_1.InsulinLimitError; } });
15
- Object.defineProperty(exports, "RecommendationError", { enumerable: true, get: function () { return RecommendationError_1.RecommendationError; } });
16
- exports.default = RecommendationScreen_1.default;
@@ -1,43 +0,0 @@
1
- import React from "react";
2
- import { BGUnit, InjectionMethod, Languages, MoodEnum } from "./types/enum";
3
- import * as Calculator from "@hedia/recommendation-calculator";
4
- import { RecommendationError } from "./utils/RecommendationError";
5
- interface IResult {
6
- suggested: number;
7
- entered?: number;
8
- }
9
- export interface IRecommendationProps {
10
- units: BGUnit;
11
- language: Languages;
12
- calculatorParams: Calculator.IRecommendationParams;
13
- injectionMethod: InjectionMethod;
14
- exitCallback(): void;
15
- removeRecommendedCarbs(): void;
16
- onRecentInsulinYes(): void;
17
- transferToLogbook(carbs: IResult, insulin: IResult, reminder: number): void;
18
- onError(error: RecommendationError): void;
19
- }
20
- interface IState {
21
- remeasureTime: number;
22
- showRecentInsulin: boolean;
23
- insulinRecommendation: number;
24
- activityReduction?: number;
25
- carbRecommendation: number;
26
- activeInsulin: number;
27
- selectedMood: MoodEnum | 0;
28
- enteredCarbs?: number;
29
- enteredInsulin?: number;
30
- }
31
- export default class RecommendationScreen extends React.Component<IRecommendationProps, IState> {
32
- private readonly timer;
33
- constructor(props: IRecommendationProps);
34
- updateRemeasureTime: (remeasureTime: number) => void;
35
- handleNoRecentInsulin: () => void;
36
- removeCarbRecommendation: () => void;
37
- handleMoodSelected: (selectedMood: IState["selectedMood"]) => void;
38
- updateCarbRecommendation: (enteredCarbs: number) => void;
39
- updateInsulinRecommendation: (enteredInsulin: number) => void;
40
- handleTransfer: () => void;
41
- render(): JSX.Element;
42
- }
43
- export {};
@@ -1,158 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
- var __importDefault = (this && this.__importDefault) || function (mod) {
22
- return (mod && mod.__esModule) ? mod : { "default": mod };
23
- };
24
- Object.defineProperty(exports, "__esModule", { value: true });
25
- const react_1 = __importDefault(require("react"));
26
- const react_native_1 = require("react-native");
27
- const enum_1 = require("./types/enum");
28
- const Constants_1 = require("./utils/Constants");
29
- const Header_1 = __importStar(require("./components/Header"));
30
- const InfoBars_1 = __importStar(require("./components/InfoBars"));
31
- const RecentInsulin_1 = __importDefault(require("./components/RecentInsulin"));
32
- const RecommendedCarbs_1 = __importDefault(require("./components/RecommendedCarbs"));
33
- const RecommendedInsulin_1 = __importDefault(require("./components/RecommendedInsulin"));
34
- const Remeasure_1 = __importDefault(require("./components/Remeasure"));
35
- const Calculator = __importStar(require("@hedia/recommendation-calculator"));
36
- const react_2 = require("@lingui/react");
37
- const Emotion_1 = __importDefault(require("./components/Emotion"));
38
- const TransferToLogbook_1 = __importDefault(require("./components/TransferToLogbook"));
39
- const RecommendationError_1 = require("./utils/RecommendationError");
40
- const i18nUtils_1 = require("./locale/i18nUtils");
41
- const Utils_1 = require("./utils/Utils");
42
- // Ignoring long timer warnings
43
- // https://github.com/facebook/react-native/issues/12981#issuecomment-652745831
44
- react_native_1.YellowBox.ignoreWarnings([`Setting a timer`]);
45
- class RecommendationScreen extends react_1.default.Component {
46
- constructor(props) {
47
- super(props);
48
- this.updateRemeasureTime = (remeasureTime) => {
49
- this.setState({
50
- remeasureTime,
51
- });
52
- };
53
- this.handleNoRecentInsulin = () => {
54
- this.setState({
55
- showRecentInsulin: false,
56
- });
57
- };
58
- this.removeCarbRecommendation = () => {
59
- this.setState({
60
- enteredCarbs: null,
61
- carbRecommendation: null,
62
- });
63
- this.props.removeRecommendedCarbs();
64
- };
65
- this.handleMoodSelected = (selectedMood) => {
66
- this.setState({
67
- selectedMood,
68
- });
69
- };
70
- this.updateCarbRecommendation = (enteredCarbs) => {
71
- this.setState({
72
- enteredCarbs,
73
- });
74
- };
75
- this.updateInsulinRecommendation = (enteredInsulin) => {
76
- this.setState({
77
- enteredInsulin,
78
- });
79
- };
80
- this.handleTransfer = () => {
81
- // TODO: Handle Errors/Warnings
82
- // 300 carbs.
83
- // < 5 mmol && activity
84
- // > 2, <= 3.5 mmol/L
85
- this.props.transferToLogbook({
86
- suggested: this.state.carbRecommendation,
87
- entered: this.state.enteredCarbs,
88
- }, {
89
- suggested: this.state.insulinRecommendation,
90
- entered: this.state.enteredInsulin,
91
- }, this.state.remeasureTime);
92
- };
93
- i18nUtils_1.changeLanguage(props.language);
94
- // Handle >= 1.1, <= 2 mmol/L (SevereHypoglycemia)
95
- const { currentBGL, recentBoluses } = props?.calculatorParams;
96
- if (currentBGL <= 2 && currentBGL >= 1.1) {
97
- props.onError(RecommendationError_1.SevereHypoglycemiaError);
98
- }
99
- const { bolus, carbRecommendation, activityReduction } = Calculator.calculateRecommendation(props.calculatorParams);
100
- this.state = {
101
- remeasureTime: 1.5,
102
- showRecentInsulin: recentBoluses?.length === 0,
103
- insulinRecommendation: Utils_1.Utils.roundValue(bolus, props.injectionMethod),
104
- activityReduction,
105
- carbRecommendation,
106
- activeInsulin: 0.0,
107
- selectedMood: 0,
108
- };
109
- this.timer = setTimeout(() => {
110
- props.onError(RecommendationError_1.TimeoutLimitError);
111
- }, enum_1.Milliseconds.Minute * 15);
112
- }
113
- render() {
114
- return (<react_2.I18nProvider language={this.props.language} i18n={i18nUtils_1.i18n}>
115
- <react_native_1.ScrollView style={containerStyles.container}>
116
- <Header_1.default exitCallback={this.props.exitCallback}/>
117
- <InfoBars_1.default label={i18nUtils_1.i18n._("Active Insulin")} value={`${this.state.activeInsulin}`} units={i18nUtils_1.i18n._("units")} showZeroAsDash={false}/>
118
- <InfoBars_1.default label={i18nUtils_1.i18n._("Blood Glucose Level")} value={`${this.props.calculatorParams.currentBGL}`} units={this.props.units} showZeroAsDash={true}/>
119
- <react_native_1.View style={containerStyles.calcContainer}>
120
- <react_native_1.View style={containerStyles.calcMargin}>
121
- <react_native_1.View style={[
122
- containerStyles.calcBorder,
123
- {
124
- borderColor: this.state.carbRecommendation
125
- ? Constants_1.BORDER_COLOUR_TEAL
126
- : Constants_1.BORDER_COLOUR_WHITE,
127
- },
128
- ]}>
129
- <RecommendedCarbs_1.default enteredCarbs={`${this.props.calculatorParams.carbohydrates}`} changedRecommendedCarbs={this.updateCarbRecommendation} recommendedCarbs={`${this.state.enteredCarbs ?? this.state.carbRecommendation}`} removeRecommendedCarbs={this.removeCarbRecommendation} onError={this.props.onError}/>
130
- <Remeasure_1.default onSliderChange={this.updateRemeasureTime} remeasureTime={this.state.remeasureTime}/>
131
- </react_native_1.View>
132
- </react_native_1.View>
133
- </react_native_1.View>
134
- {this.state.showRecentInsulin ? (<RecentInsulin_1.default onRecentInsulinYes={this.props.onRecentInsulinYes} onRecentInsulinNo={this.handleNoRecentInsulin}/>) : (<RecommendedInsulin_1.default injectionMethod={this.props.injectionMethod} insulinRecommendation={this.state.enteredInsulin ?? this.state.insulinRecommendation} activityReduction={this.state.activityReduction} updateRecommendedInsulin={this.updateInsulinRecommendation} onError={this.props.onError}/>)}
135
- <Emotion_1.default moodSelected={this.handleMoodSelected}/>
136
- <TransferToLogbook_1.default visible={!this.state.showRecentInsulin} transfer={this.handleTransfer}/>
137
- </react_native_1.ScrollView>
138
- </react_2.I18nProvider>);
139
- }
140
- }
141
- exports.default = RecommendationScreen;
142
- const containerStyles = react_native_1.StyleSheet.create({
143
- container: {
144
- flex: 1,
145
- backgroundColor: Constants_1.BACKGROUND_COLOUR_PURPLE,
146
- },
147
- calcContainer: {
148
- flex: 1,
149
- },
150
- calcMargin: {
151
- flex: 1,
152
- margin: Header_1.headerStyles.margin.margin,
153
- },
154
- calcBorder: {
155
- ...InfoBars_1.infoStyles.border,
156
- borderColor: Constants_1.BORDER_COLOUR_TEAL,
157
- },
158
- });
@@ -1,14 +0,0 @@
1
- import React from "react";
2
- import { MoodEnum } from "../types/enum";
3
- interface IProps {
4
- moodSelected(mood: MoodEnum | 0): void;
5
- }
6
- interface IState {
7
- selected: MoodEnum | 0;
8
- }
9
- export default class Emotion extends React.Component<IProps, IState> {
10
- state: IState;
11
- handleIconPress: (selected: number, toggle: boolean) => void;
12
- render(): JSX.Element;
13
- }
14
- export {};