@hedia/recommendation-screen 2.0.2 → 2.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 (114) hide show
  1. package/App.d.ts +2 -2
  2. package/coverage/clover.xml +700 -0
  3. package/coverage/coverage-final.json +28 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +79 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +201 -0
  8. package/coverage/lcov-report/prettify.css +1 -0
  9. package/coverage/lcov-report/prettify.js +2 -0
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/sorter.js +170 -0
  12. package/coverage/lcov-report/src/RecommendationScreen.tsx.html +1460 -0
  13. package/coverage/lcov-report/src/__tests__/index.html +111 -0
  14. package/coverage/lcov-report/src/__tests__/utils.tsx.html +512 -0
  15. package/coverage/lcov-report/src/components/Header.tsx.html +347 -0
  16. package/coverage/lcov-report/src/components/InfoBars.tsx.html +404 -0
  17. package/coverage/lcov-report/src/components/InvisibleNumberInput.tsx.html +374 -0
  18. package/coverage/lcov-report/src/components/LimitationMessage.tsx.html +191 -0
  19. package/coverage/lcov-report/src/components/LineSeparator.tsx.html +152 -0
  20. package/coverage/lcov-report/src/components/RecentInsulin.tsx.html +383 -0
  21. package/coverage/lcov-report/src/components/RecommendationModal.tsx.html +737 -0
  22. package/coverage/lcov-report/src/components/RecommendedCarbs.tsx.html +857 -0
  23. package/coverage/lcov-report/src/components/RecommendedInsulin.tsx.html +605 -0
  24. package/coverage/lcov-report/src/components/Remeasure.tsx.html +440 -0
  25. package/coverage/lcov-report/src/components/TransferToLogbook.tsx.html +380 -0
  26. package/coverage/lcov-report/src/components/TwoOptionModal.tsx.html +635 -0
  27. package/coverage/lcov-report/src/components/activity/Activity.tsx.html +311 -0
  28. package/coverage/lcov-report/src/components/activity/ActivityIcon.tsx.html +242 -0
  29. package/coverage/lcov-report/src/components/activity/ActivityIntensity.tsx.html +257 -0
  30. package/coverage/lcov-report/src/components/activity/index.html +141 -0
  31. package/coverage/lcov-report/src/components/index.html +276 -0
  32. package/coverage/lcov-report/src/components/mood/Emotion.tsx.html +278 -0
  33. package/coverage/lcov-report/src/components/mood/MoodIcon.tsx.html +260 -0
  34. package/coverage/lcov-report/src/components/mood/index.html +126 -0
  35. package/coverage/lcov-report/src/index.html +111 -0
  36. package/coverage/lcov-report/src/locale/i18nUtils.ts.html +161 -0
  37. package/coverage/lcov-report/src/locale/index.html +111 -0
  38. package/coverage/lcov-report/src/utils/AttentionMessages.tsx.html +326 -0
  39. package/coverage/lcov-report/src/utils/Constants.ts.html +176 -0
  40. package/coverage/lcov-report/src/utils/RecommendationError.tsx.html +500 -0
  41. package/coverage/lcov-report/src/utils/RecommendationUtils.ts.html +467 -0
  42. package/coverage/lcov-report/src/utils/Translations.ts.html +107 -0
  43. package/coverage/lcov-report/src/utils/Utils.ts.html +263 -0
  44. package/coverage/lcov-report/src/utils/Validations.ts.html +815 -0
  45. package/coverage/lcov-report/src/utils/index.html +201 -0
  46. package/coverage/lcov.info +1581 -0
  47. package/jest.config.js +2 -1
  48. package/package.json +2 -2
  49. package/src/RecommendationScreen.d.ts +2 -3
  50. package/src/__tests__/components/Emotion.test.jsx +7 -8
  51. package/src/components/Icon.d.ts +13 -0
  52. package/src/components/Icon.jsx +42 -0
  53. package/src/components/LimitationMessage.d.ts +1 -2
  54. package/src/components/RecommendationModal.d.ts +2 -3
  55. package/src/components/RecommendationModal.jsx +2 -1
  56. package/src/components/activity/ActivityIntensity.jsx +4 -3
  57. package/src/utils/AttentionMessages.d.ts +16 -10
  58. package/src/utils/AttentionMessages.jsx +15 -10
  59. package/src/utils/RecommendationUtils.d.ts +2 -3
  60. package/src/utils/RecommendationUtils.js +10 -6
  61. package/src/utils/Utils.d.ts +1 -0
  62. package/src/utils/Utils.js +4 -0
  63. package/tsconfig.json +7 -5
  64. package/App.tsx +0 -140
  65. package/index.ts +0 -6
  66. package/src/RecommendationScreen.tsx +0 -461
  67. package/src/__tests__/RecommendationScreen.test.tsx +0 -1231
  68. package/src/__tests__/RecommendationUtils.test.ts +0 -332
  69. package/src/__tests__/Translate.test.tsx +0 -31
  70. package/src/__tests__/Utils.test.ts +0 -91
  71. package/src/__tests__/Validations.test.ts +0 -648
  72. package/src/__tests__/components/Activity.test.tsx +0 -163
  73. package/src/__tests__/components/Emotion.test.tsx +0 -110
  74. package/src/__tests__/components/Header.test.tsx +0 -44
  75. package/src/__tests__/components/InfoBars.test.tsx +0 -152
  76. package/src/__tests__/components/InvisibleNumberInput.test.tsx +0 -294
  77. package/src/__tests__/components/LimitationMessage.test.tsx +0 -58
  78. package/src/__tests__/components/MoodIcon.test.tsx +0 -45
  79. package/src/__tests__/components/RecommendationModal.test.tsx +0 -169
  80. package/src/__tests__/components/RecommendedCarbs.test.tsx +0 -234
  81. package/src/__tests__/components/RecommendedInsulin.test.tsx +0 -241
  82. package/src/__tests__/components/Remeasure.test.tsx +0 -97
  83. package/src/__tests__/components/TransferToLogbook.test.tsx +0 -38
  84. package/src/__tests__/components/TwoOptionModal.test.tsx +0 -72
  85. package/src/__tests__/utils.tsx +0 -144
  86. package/src/components/Header.tsx +0 -89
  87. package/src/components/Icon.js +0 -41
  88. package/src/components/InfoBars.tsx +0 -108
  89. package/src/components/InvisibleNumberInput.tsx +0 -98
  90. package/src/components/LimitationMessage.tsx +0 -38
  91. package/src/components/LineSeparator.tsx +0 -24
  92. package/src/components/RecentInsulin.tsx +0 -101
  93. package/src/components/RecommendationModal.tsx +0 -224
  94. package/src/components/RecommendedCarbs.tsx +0 -259
  95. package/src/components/RecommendedInsulin.tsx +0 -175
  96. package/src/components/Remeasure.tsx +0 -120
  97. package/src/components/TransferToLogbook.tsx +0 -100
  98. package/src/components/TwoOptionModal.tsx +0 -185
  99. package/src/components/activity/Activity.tsx +0 -77
  100. package/src/components/activity/ActivityIcon.tsx +0 -54
  101. package/src/components/activity/ActivityIntensity.tsx +0 -58
  102. package/src/components/mood/Emotion.tsx +0 -66
  103. package/src/components/mood/MoodIcon.tsx +0 -60
  104. package/src/locale/CleanLanguage.ts +0 -13
  105. package/src/locale/i18nUtils.ts +0 -27
  106. package/src/types/enum.ts +0 -108
  107. package/src/types/types.ts +0 -16
  108. package/src/utils/AttentionMessages.tsx +0 -75
  109. package/src/utils/Constants.ts +0 -32
  110. package/src/utils/RecommendationError.tsx +0 -140
  111. package/src/utils/RecommendationUtils.ts +0 -125
  112. package/src/utils/Translations.ts +0 -9
  113. package/src/utils/Utils.ts +0 -57
  114. package/src/utils/Validations.ts +0 -245
@@ -1,60 +0,0 @@
1
- import { Logbook } from "@hedia/types";
2
- import React from "react";
3
- import { Dimensions, Image, ImageURISource, StyleSheet, TouchableOpacity } from "react-native";
4
-
5
- const MoodEnum = Logbook.Enums.MoodEnum;
6
-
7
- interface IProps {
8
- mood: Logbook.Enums.MoodEnum;
9
- active: boolean;
10
- onPress(toggle: boolean): void;
11
- }
12
-
13
- const MOODS_INACTIVE: Record<number, ImageURISource> = {
14
- 1: require(`../../assets/mood/sad.png`),
15
- 2: require(`../../assets/mood/semi_sad.png`),
16
- 3: require(`../../assets/mood/neutral.png`),
17
- 4: require(`../../assets/mood/semi_happy.png`),
18
- 5: require(`../../assets/mood/happy.png`),
19
- };
20
-
21
- const MOODS_ACTIVE: Record<number, ImageURISource> = {
22
- 1: require(`../../assets/mood/sad_active.png`),
23
- 2: require(`../../assets/mood/semi_sad_active.png`),
24
- 3: require(`../../assets/mood/neutral_active.png`),
25
- 4: require(`../../assets/mood/semi_happy_active.png`),
26
- 5: require(`../../assets/mood/happy_active.png`),
27
- };
28
-
29
- export default class MoodIcon extends React.Component<IProps> {
30
- public getMoodIcon = (): ImageURISource => {
31
- if (this.props.active) {
32
- return MOODS_ACTIVE[this.props.mood];
33
- }
34
- return MOODS_INACTIVE[this.props.mood];
35
- };
36
-
37
- public handleOnPress = (): void => {
38
- this.props.onPress(!this.props.active);
39
- };
40
-
41
- public render(): JSX.Element {
42
- const { mood, active } = this.props;
43
- const label = `${MoodEnum[mood]}_${active}`;
44
- return (
45
- <TouchableOpacity style={moodIconStyles.container} onPress={this.handleOnPress} accessibilityLabel={label}>
46
- <Image style={moodIconStyles.icon} source={this.getMoodIcon()} />
47
- </TouchableOpacity>
48
- );
49
- }
50
- }
51
-
52
- const moodIconStyles = StyleSheet.create({
53
- container: {
54
- marginHorizontal: `1%`,
55
- },
56
- icon: {
57
- width: Dimensions.get(`screen`).width / 8,
58
- height: Dimensions.get(`screen`).width / 8,
59
- },
60
- });
@@ -1,13 +0,0 @@
1
- const fs = require(`fs`);
2
- const path = require(`path`);
3
-
4
- const LOCALE_PATH = `./src/locale`;
5
- // tslint:disable:typedef
6
- const dir = fs.readdirSync(LOCALE_PATH).filter((name) => name.length === 2);
7
-
8
- dir.forEach((element) => {
9
- const filePath = path.resolve(LOCALE_PATH, element, `messages.po`);
10
- const fileData = fs.readFileSync(filePath).toString(`utf-8`);
11
- console.log(`Compiling ${filePath}`);
12
- fs.writeFileSync(filePath, fileData.replace(/(msgstr.*?)\\\\n(.*)/g, `$1\\n$2`));
13
- });
@@ -1,27 +0,0 @@
1
- import { Languages } from "@hedia/types";
2
- import { Catalog, I18n, setupI18n } from "@lingui/core";
3
- import moment from "moment";
4
- // tslint:disable-next-line:no-import-side-effect
5
- import "moment/min/locales";
6
-
7
- const languageMap: Record<Languages, Catalog> = {
8
- [Languages.da]: require(`./da/messages.js`),
9
- [Languages.en]: require(`./en/messages.js`),
10
- [Languages.de]: require(`./de/messages.js`),
11
- [Languages.es]: require(`./es/messages.js`),
12
- [Languages.fr]: require(`./fr/messages.js`),
13
- [Languages.it]: require(`./it/messages.js`),
14
- };
15
-
16
- export const i18n = setupI18n({
17
- language: Languages.en,
18
- catalogs: languageMap,
19
- });
20
-
21
- export function changeLanguage(language: Languages): I18n {
22
- languageMap[language] ? i18n.activate(language) : i18n.activate(Languages.en);
23
- // Temporary way of setting the moment locale to en-gb since we currently identify GB English with "en".
24
- const linguiLocale = language === Languages.en ? `en-gb` : language;
25
- moment.locale(linguiLocale);
26
- return i18n;
27
- }
package/src/types/enum.ts DELETED
@@ -1,108 +0,0 @@
1
- export enum ActivityTestIds {
2
- ActivityReduction = `activity-reduction-percentage`,
3
- }
4
-
5
- export enum HeaderTestIds {
6
- ExitCalculation = `exit-calculation-button`,
7
- }
8
-
9
- export enum LimitationMessageTestIds {
10
- OkButton = `limitation-message-ok-button`,
11
- }
12
-
13
- export enum RecentInsulinTestIds {
14
- No = "recent-insulin-no",
15
- Yes = "recent-insulin-yes",
16
- }
17
-
18
- export enum RecommendedCarbsTestIds {
19
- RecommendedCarbs = "recommended-carbs",
20
- EditRecommendedCarbs = `edit-recommended-carbs`,
21
- InvisibleCarbInput = `invisible-recommended-carbs-input`,
22
- EnteredCarbs = "entered-carbs",
23
- RemoveRecommendation = `remove-carb-recommendation`,
24
- TotalCarbs = "total-carbs",
25
- }
26
-
27
- export enum RecommendedInsulinTestIds {
28
- EditRecommendedInsulin = `edit-recommended-insulin`,
29
- InvisibleInsulinInput = `invisible-recommended-insulin-input`,
30
- ShownInsulinText = `shown-insulin-text`,
31
- }
32
-
33
- export enum RecommendationModalTestIds {
34
- DeclineCarbs = "recommendation-modal-decline-carbs",
35
- AcceptCarbs = "recommendation-modal-accept-carbs",
36
- OkButton = "recommendation-modal-ok-button",
37
- SuggestedCarbs = `recommendation-modal-suggested-carbs`,
38
- }
39
-
40
- export enum RemeasureTestIds {
41
- RemeasureSlider = `remeasure-slider`,
42
- }
43
-
44
- export enum TransferToLogbookTestIds {
45
- TransferButton = "transfer-to-logbook-button",
46
- }
47
-
48
- export enum TwoOptionModalTestIds {
49
- ExitButton = `exit-two-option-modal`,
50
- FirstOption = `first-option-button`,
51
- SecondOption = `second-option-button`,
52
- }
53
-
54
- export type TestIdEnum =
55
- | ActivityTestIds
56
- | HeaderTestIds
57
- | LimitationMessageTestIds
58
- | RecentInsulinTestIds
59
- | RecommendedCarbsTestIds
60
- | RecommendedInsulinTestIds
61
- | RecommendationModalTestIds
62
- | RemeasureTestIds
63
- | TransferToLogbookTestIds
64
- | TwoOptionModalTestIds;
65
-
66
- export enum RecommendationErrorEnum {
67
- ActivityDuration,
68
- ActivityTargetBGL,
69
- ActivitySettings,
70
- ActivityDate,
71
- ActivityIntensity,
72
- ActivityType,
73
- BolusInsulinDose,
74
- BolusInsulinSecondsPassed,
75
- RecentBolus,
76
- CarbohydrateLimit,
77
- InsulinSensitivity,
78
- InsulinToCarbsRatio,
79
- LatestLogbook6HoursBGL,
80
- CurrentBGL,
81
- CurrentBKL,
82
- TargetBGL,
83
- UserReminder,
84
- Language,
85
- InjectionMethod,
86
- BloodKetoneUnit,
87
- BloodGlucoseUnit,
88
- }
89
-
90
- export enum BgLevel {
91
- SevereHypoglycemia,
92
- Hypoglycemia,
93
- MildHypoglycemia,
94
- Normoglycemia,
95
- NormoglycemiaUnder5MMOL,
96
- MildHyperglycemia,
97
- Hyperglycemia,
98
- SevereHyperglycemia,
99
- UnsupportedBGLevel,
100
- BGLevelNotProvided,
101
- }
102
-
103
- export enum RecommendationReminders {
104
- ReminderOff = 0,
105
- Reminder15Minutes = 0.25,
106
- Reminder60Minutes = 1,
107
- HediaReminderDefault = 1.5,
108
- }
@@ -1,16 +0,0 @@
1
- import { Activity, BolusCalculator, Logbook } from "@hedia/types";
2
-
3
- export interface IInterval {
4
- min: number;
5
- max: number;
6
- }
7
- export interface IActivityDisplayProps {
8
- activityTitle: string | null;
9
- activityType: Activity.Enums.ActivityEnum | null;
10
- }
11
- export type IActivityParams = BolusCalculator.Types.IActivityParams;
12
- export type logbookEntry = Logbook.Types.ILogbookEntry;
13
- export type IRecommendationParams = BolusCalculator.Types.IRecommendationParams;
14
- export type ReductionType = Activity.Types.ReductionType;
15
- export type ActivitySettings = Activity.Types.ActivitySettings;
16
- export type IRecentBolus = BolusCalculator.Types.IRecentBolus;
@@ -1,75 +0,0 @@
1
- import { BolusCalculator } from "@hedia/types";
2
- import { t } from "@lingui/macro";
3
- import moment from "moment";
4
- import { i18n } from "../locale/i18nUtils";
5
-
6
- export class AttentionMessage {
7
- public static SevereHypoglycemia = (): string => `${Messages.VeryLowBGL()}${`\n`}${Messages.Reminder15Minutes()}`;
8
- public static Hypoglycemia = (): string => `${Messages.LowBGL()}${`\n`}${Messages.Reminder15Minutes()}`;
9
- public static MildHypoglycemia = (): string => Messages.Reminder15Minutes();
10
- public static NormoglycemiaActivityUnder5MMOL = (): string => Messages.PostponePhysicalActivityUnder5MMOL();
11
- public static HyperglycemiaActivity = (): string =>
12
- `${Messages.HighBGL()}${`\n`}${Messages.InsulinKetones()}${`\n`}${Messages.Reminder15Minutes()}${`\n`}${Messages.PostponePhysicalActivity()}`;
13
- public static SevereHyperglycemia = (): string => `${Messages.HighBGL()}${`\n`}${Messages.InsulinKetones()}${`\n`}`;
14
- public static SevereHyperglycemiaActivity = (): string => AttentionMessage.HyperglycemiaActivity();
15
- }
16
-
17
- export function addPostponeActivityMessageUnder5MMOL(message: AttentionMessage): string {
18
- return `${message}${`\n`}${Messages.PostponePhysicalActivityUnder5MMOL()}`;
19
- }
20
-
21
- const SAFETY_INSULIN_LIMIT = BolusCalculator.Constants.SAFETY_INSULIN_LIMIT;
22
-
23
- function getLimitedValue(reduction: number): number {
24
- return SAFETY_INSULIN_LIMIT - SAFETY_INSULIN_LIMIT * reduction;
25
- }
26
-
27
- export class Messages {
28
- public static VeryLowBGL = (): string =>
29
- i18n._(
30
- t`Your blood glucose level is very low. Take glucagon or eat carbohydrates if possible. Seek medical attention.`,
31
- );
32
- public static LowBGL = (): string => i18n._(t`Your blood glucose level is very low.`);
33
- public static Reminder15Minutes = (): string =>
34
- i18n._(t`You will be reminded to measure your blood glucose level in 15 min.`);
35
- public static PostponePhysicalActivity = (): string =>
36
- i18n._(t`If it is possible, postpone your planned exercise.`);
37
- public static PostponePhysicalActivityUnder5MMOL = (): string =>
38
- i18n._(
39
- t`Consider not to initiate physical activity before your blood glucose level is within the recommended ranges prior to physical activity.`,
40
- );
41
- public static HighBGL = (): string => i18n._(t`You have a high blood glucose level.`);
42
- public static InsulinKetones = (): string => i18n._(t`You should take rapid-acting insulin and measure ketones.`);
43
- public static RecommendationWasLimited = (): string =>
44
- i18n._(
45
- t`Your recommendation would have been higher than ${SAFETY_INSULIN_LIMIT} units of insulin, but it has been limited for safety reasons.
46
- Hedia never recommends more than ${SAFETY_INSULIN_LIMIT} units of insulin per calculation.`,
47
- );
48
- public static RecommendationWasLimitedActivity = (activityReduction: number): string =>
49
- i18n._(
50
- t`Your recommendation would have been higher than ${getLimitedValue(activityReduction)}
51
- units of insulin, but it has been limited for safety reasons.${`\n\n`}
52
- Hedia never recommends more than ${SAFETY_INSULIN_LIMIT}
53
- units of insulin per calculation, but because of the physical activity
54
- you entered it has been further reduced by ${(activityReduction * 100).toFixed(0)}% to
55
- ${getLimitedValue(activityReduction)}.`,
56
- );
57
- public static InsulinInputWasLimited = (activityReduction: number | null): string =>
58
- activityReduction
59
- ? i18n._(
60
- t`Hedia doesn't support more than ${SAFETY_INSULIN_LIMIT} units of insulin per calculation, but because of the physical activity you entered it has been further reduced by
61
- ${(activityReduction * 100).toFixed(0)}% to ${getLimitedValue(activityReduction)} units for this calculation.`,
62
- )
63
- : i18n._(t`Hedia does not support more than ${SAFETY_INSULIN_LIMIT} units of insulin per calculation.`);
64
- public static TimeoutPrompTitle = (): string =>
65
- i18n._(t`More than 15 minutes has passed since this calculation was started.`);
66
- public static TimeoutRecommendationNotVisible = (): string =>
67
- i18n._(t`Please go through the calculation steps with new measurements to ensure a safe recommendation.`);
68
- public static TimeoutRecommendationVisible = (date: Date): string => {
69
- const day = moment(date).format(`LL`);
70
- const time = moment(date).format(`HH:mm`);
71
- return i18n._(
72
- t`Recommendation from ${day} at ${time} was not transfered to your logbook.${`\n`}Did you use the recommendation?`,
73
- );
74
- };
75
- }
@@ -1,32 +0,0 @@
1
- import { IInterval } from "../types/types";
2
-
3
- export const BACKGROUND_COLOUR_PURPLE = `rgba(27, 31, 72, 1)`;
4
- export const BORDER_COLOUR_GREY = `rgba(74, 91, 134, 1)`;
5
- export const BORDER_COLOUR_TEAL = `rgba(1, 255, 252, 0.8)`;
6
-
7
- export const SEVERE_HYPERGLYCEMIA_START_MMOL = 15;
8
-
9
- export const FOUR_HOURS_SECONDS = 14400;
10
- export const ONE_HOUR_MINUTES = 60;
11
- export const ACTIVITY_BUFFER_MINUTES = 10;
12
-
13
- export const CARBOHYDRATES_LIMTS: IInterval = { min: 0, max: 300 };
14
- export const INSULIN_DOSE_LIMITS: IInterval = { min: 0, max: 50 };
15
- export const BOLUS_SECONDS_PASSED_LIMITS: IInterval = { min: 0, max: FOUR_HOURS_SECONDS };
16
-
17
- export const ACTIVITY_DURATION_MINUTES_LIMITS: IInterval = { min: 1, max: ONE_HOUR_MINUTES };
18
- export const INSULIN_SENSITIVITY_MMOL_LIMITS: IInterval = { min: 0.3, max: 10 };
19
- export const INSULIN_TO_CARBS_RATIO_LIMITS: IInterval = { min: 1, max: 50 };
20
-
21
- export const CURRENT_BGL_MMOL_LIMITS: IInterval = { min: 1.1, max: 33.3 };
22
- export const MMOLL_PER_MGDL_BGL: number = 0.0555;
23
- export const MGDL_PER_MMOLL_BGL: number = 1 / MMOLL_PER_MGDL_BGL;
24
-
25
- export const CURRENT_BKL_MMOL_LIMITS: IInterval = { min: 0, max: 8 };
26
- export const MMOLL_PER_MGDL_BKL: number = 0.096;
27
- export const MGDL_PER_MMOLL_BKL: number = 1 / MMOLL_PER_MGDL_BKL;
28
-
29
- export const TARGET_BGL_MMOL_LIMITS: IInterval = { min: 5, max: 13.9 };
30
- export const ACTIVITY_TARGET_BGL_MMOL_LIMITS: IInterval = { min: 5, max: 13.9 };
31
- export const REMINDER_HOURS_LIMITS: IInterval = { min: 0, max: 6 };
32
- export const ACTIVITY_SETTINGS_INTERVAL_LIMITS: IInterval = { min: 0, max: 1 };
@@ -1,140 +0,0 @@
1
- import { BolusCalculator } from "@hedia/types";
2
- import { t } from "@lingui/macro";
3
- import { i18n } from "../locale/i18nUtils";
4
- import { RecommendationErrorEnum } from "../types/enum";
5
-
6
- const SAFETY_INSULIN_LIMIT = BolusCalculator.Constants.SAFETY_INSULIN_LIMIT;
7
-
8
- export class RecommendationError extends Error {
9
- public readonly type: RecommendationErrorEnum;
10
-
11
- constructor(message: string, type: RecommendationErrorEnum) {
12
- super(message);
13
- this.type = type;
14
- }
15
- }
16
-
17
- export const ActivitySettingsError = (): RecommendationError =>
18
- new RecommendationError(
19
- i18n._(t`Error. Please verify that your activity settings are set up correctly.`),
20
- RecommendationErrorEnum.ActivitySettings,
21
- );
22
-
23
- export const ActivityDurationError = (): RecommendationError =>
24
- new RecommendationError(
25
- i18n._(t`Error. Hedia Calculator only supports activities with a duration of maximum 60 minutes.`),
26
- RecommendationErrorEnum.ActivityDuration,
27
- );
28
-
29
- export const ActivityDateError = (): RecommendationError =>
30
- new RecommendationError(
31
- i18n._(t`Hedia Calculator does not support activities that finished more than 4 hours ago.`),
32
- RecommendationErrorEnum.ActivityDate,
33
- );
34
-
35
- export const ActivityIntensityError = (): RecommendationError =>
36
- new RecommendationError(
37
- i18n._(t`Error. Hedia Calculator does not support your activity intensity value`),
38
- RecommendationErrorEnum.ActivityIntensity,
39
- );
40
- export const ActivityTypeError = (): RecommendationError =>
41
- new RecommendationError(
42
- i18n._(t`Error. Hedia Calculator does not support your activity type value`),
43
- RecommendationErrorEnum.ActivityType,
44
- );
45
-
46
- export const ActivityTargetBGLError = (): RecommendationError =>
47
- new RecommendationError(
48
- i18n._(t`Error. Please verify that your activity target blood glucose value is correct.`),
49
- RecommendationErrorEnum.ActivityTargetBGL,
50
- );
51
-
52
- export const CarbohydrateLimitError = (): RecommendationError =>
53
- new RecommendationError(
54
- i18n._(
55
- t`Hedia Calculator does not support insulin recommendations with more than 300 grams of carbohydrates present.`,
56
- ),
57
- RecommendationErrorEnum.CarbohydrateLimit,
58
- );
59
-
60
- export const InsulinSensitivityError = (): RecommendationError =>
61
- new RecommendationError(
62
- i18n._(t`Error. Please verify that your insulin sensitivity value is correct.`),
63
- RecommendationErrorEnum.InsulinSensitivity,
64
- );
65
-
66
- export const InsulinToCarbsRatioError = (): RecommendationError =>
67
- new RecommendationError(
68
- i18n._(t`Error. Please verify that your insulin to carb ratio value is correct.`),
69
- RecommendationErrorEnum.InsulinToCarbsRatio,
70
- );
71
-
72
- export const CurrentBGLError = (): RecommendationError =>
73
- new RecommendationError(
74
- i18n._(t`Error. Hedia Calculator does not support your current blood glucose level.`),
75
- RecommendationErrorEnum.CurrentBGL,
76
- );
77
- export const LatestLogbook6HoursBGLError = (): RecommendationError =>
78
- new RecommendationError(
79
- i18n._(
80
- t`Error. Hedia Calculator does not support the blood glucose level of your latest logbook entry from the last 6 hours.`,
81
- ),
82
- RecommendationErrorEnum.LatestLogbook6HoursBGL,
83
- );
84
- export const CurrentBKLError = (): RecommendationError =>
85
- new RecommendationError(
86
- i18n._(t`Error. Hedia Calculator does not support your current blood ketone level.`),
87
- RecommendationErrorEnum.CurrentBKL,
88
- );
89
-
90
- export const TargetBGLError = (): RecommendationError =>
91
- new RecommendationError(
92
- i18n._(t`Error. Please verify that your target blood glucose value is correct.`),
93
- RecommendationErrorEnum.TargetBGL,
94
- );
95
-
96
- export const BolusInsulinDoseError = (): RecommendationError =>
97
- new RecommendationError(
98
- i18n._(t`Error. Hedia Calculator does not support an insulin dose greater than ${SAFETY_INSULIN_LIMIT} units`),
99
- RecommendationErrorEnum.BolusInsulinDose,
100
- );
101
-
102
- export const BolusInsulinSecondsPassedError = (): RecommendationError =>
103
- new RecommendationError(
104
- i18n._(t`Error. Hedia Calculator does not support insulin recommendations with boluses older than 4 hours`),
105
- RecommendationErrorEnum.BolusInsulinSecondsPassed,
106
- );
107
-
108
- export const RecentBolusError = (): RecommendationError =>
109
- new RecommendationError(
110
- i18n._(t`Error. Hedia Calculator could not find your recent boluses`),
111
- RecommendationErrorEnum.RecentBolus,
112
- );
113
-
114
- export const UserReminderError = (): RecommendationError =>
115
- new RecommendationError(
116
- i18n._(t`Error. Please verify your notifications settings.`),
117
- RecommendationErrorEnum.UserReminder,
118
- );
119
-
120
- export const InjectionMethodError = (): RecommendationError =>
121
- new RecommendationError(
122
- i18n._(t`Error. Hedia Calculator does not support your injection method.`),
123
- RecommendationErrorEnum.InjectionMethod,
124
- );
125
-
126
- export const LanguageError = (): RecommendationError =>
127
- new RecommendationError(
128
- i18n._(t`Error. Hedia Calculator does not support your current language.`),
129
- RecommendationErrorEnum.Language,
130
- );
131
- export const BloodKetoneUnitError = (): RecommendationError =>
132
- new RecommendationError(
133
- i18n._(t`Error. Hedia Calculator does not support your current blood ketone unit.`),
134
- RecommendationErrorEnum.BloodKetoneUnit,
135
- );
136
- export const BloodGlucoseUnitError = (): RecommendationError =>
137
- new RecommendationError(
138
- i18n._(t`Error. Hedia Calculator does not support your current blood glucose unit.`),
139
- RecommendationErrorEnum.BloodGlucoseUnit,
140
- );
@@ -1,125 +0,0 @@
1
- import moment from "moment";
2
- import { BgLevel, RecommendationReminders } from "../types/enum";
3
- import { IActivityParams, logbookEntry } from "../types/types";
4
- import { addPostponeActivityMessageUnder5MMOL, AttentionMessage, Messages } from "./AttentionMessages";
5
- import { SEVERE_HYPERGLYCEMIA_START_MMOL } from "./Constants";
6
- import { CurrentBGLError } from "./RecommendationError";
7
-
8
- export function getBGLevel(currentBGL: number, latestLogbookFrom6Hours: logbookEntry | null): BgLevel {
9
- if (currentBGL === null) {
10
- return BgLevel.BGLevelNotProvided;
11
- }
12
- if (currentBGL >= 1.1 && currentBGL <= 2) {
13
- return BgLevel.SevereHypoglycemia;
14
- }
15
- if (currentBGL > 2 && currentBGL <= 3.5) {
16
- return BgLevel.Hypoglycemia;
17
- }
18
- if (currentBGL > 3.5 && currentBGL <= 4) {
19
- return BgLevel.MildHypoglycemia;
20
- }
21
- if (currentBGL > 4 && currentBGL < 5) {
22
- return BgLevel.NormoglycemiaUnder5MMOL;
23
- }
24
- if (currentBGL >= 5 && currentBGL <= 7) {
25
- return BgLevel.Normoglycemia;
26
- }
27
- if (currentBGL > 7 && currentBGL < 15) {
28
- return BgLevel.MildHyperglycemia;
29
- }
30
- if (
31
- currentBGL > 15 && currentBGL <= 33.3 && latestLogbookFrom6Hours
32
- ? isSevereHyperglycemia(latestLogbookFrom6Hours)
33
- : false
34
- ) {
35
- return BgLevel.SevereHyperglycemia;
36
- }
37
- if (currentBGL >= 15 && currentBGL <= 33.3) {
38
- return BgLevel.Hyperglycemia;
39
- }
40
- return BgLevel.UnsupportedBGLevel;
41
- }
42
-
43
- export function getReminder(
44
- bgLevel: BgLevel,
45
- carbohydrates: number,
46
- userReminder: number,
47
- activity: IActivityParams | null,
48
- ): number {
49
- const reminder = userReminder === undefined ? RecommendationReminders.HediaReminderDefault : userReminder;
50
- switch (bgLevel) {
51
- case BgLevel.SevereHypoglycemia:
52
- case BgLevel.Hypoglycemia:
53
- case BgLevel.MildHypoglycemia:
54
- return RecommendationReminders.Reminder15Minutes;
55
-
56
- case BgLevel.NormoglycemiaUnder5MMOL:
57
- case BgLevel.Normoglycemia:
58
- case BgLevel.MildHyperglycemia:
59
- case BgLevel.BGLevelNotProvided:
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: IActivityParams | null): AttentionMessage | null {
74
- switch (bgLevel) {
75
- case BgLevel.BGLevelNotProvided:
76
- case BgLevel.Normoglycemia:
77
- case BgLevel.MildHyperglycemia:
78
- return null;
79
-
80
- case BgLevel.NormoglycemiaUnder5MMOL:
81
- return isActivityWithin15Minutes(activity) ? AttentionMessage.NormoglycemiaActivityUnder5MMOL() : null;
82
-
83
- case BgLevel.SevereHypoglycemia:
84
- case BgLevel.Hypoglycemia:
85
- case BgLevel.MildHypoglycemia:
86
- return isActivityWithin15Minutes(activity)
87
- ? addPostponeActivityMessageUnder5MMOL(AttentionMessage[BgLevel[bgLevel]]())
88
- : AttentionMessage[BgLevel[bgLevel]]();
89
-
90
- case BgLevel.Hyperglycemia:
91
- return isActivityWithin15Minutes(activity) ? AttentionMessage.HyperglycemiaActivity() : null;
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(logbook?: logbookEntry | null): boolean {
103
- if (logbook !== null && logbook !== undefined) {
104
- const { blood_glucose_millimolar } = logbook;
105
- if (blood_glucose_millimolar !== null) {
106
- return blood_glucose_millimolar > SEVERE_HYPERGLYCEMIA_START_MMOL;
107
- }
108
- }
109
-
110
- return false;
111
- }
112
-
113
- export function isActivityWithin15Minutes(activity: IActivityParams | null): boolean {
114
- const minutes = activity?.activityDuration;
115
- return moment
116
- .utc(activity?.activityDate)
117
- .isBetween(moment.utc().subtract(minutes, `minutes`), moment.utc().add(15, `minutes`));
118
- }
119
-
120
- export function getLimitationMessage(wasLimited: boolean, activityReduction: number | null): Messages | null {
121
- const message = activityReduction
122
- ? Messages.RecommendationWasLimitedActivity(activityReduction)
123
- : Messages.RecommendationWasLimited();
124
- return wasLimited ? message : null;
125
- }
@@ -1,9 +0,0 @@
1
- import { Activity } from "@hedia/types";
2
- import { t } from "@lingui/macro";
3
- import { i18n } from "../locale/i18nUtils";
4
-
5
- export const ActivityIntensityTranslations: Record<Activity.Enums.ActivityIntensity, () => string> = {
6
- light: (): string => i18n._(t`Light`),
7
- moderate: (): string => i18n._(t`Moderate`),
8
- hard: (): string => i18n._(t`Hard`),
9
- };
@@ -1,57 +0,0 @@
1
- import { BloodGlucoseUnit, BloodKetonesUnit, UserSettings } from "@hedia/types";
2
- import { IInterval } from "../types/types";
3
- import { MGDL_PER_MMOLL_BGL, MGDL_PER_MMOLL_BKL } from "./Constants";
4
-
5
- const InjectionMethod = UserSettings.Enums.InjectionMethod;
6
- const { PenHalf, PenWhole, Pump } = InjectionMethod;
7
-
8
- export class Utils {
9
- public static getRounding(method: UserSettings.Enums.InjectionMethod): number {
10
- switch (method) {
11
- case PenWhole:
12
- return 1;
13
-
14
- case PenHalf:
15
- return 2;
16
-
17
- case Pump:
18
- return 10;
19
-
20
- default:
21
- throw Error(`Unsupported InjectionMethod: ${method}`);
22
- }
23
- }
24
-
25
- public static roundValue(value: number, injectMethod: UserSettings.Enums.InjectionMethod): number {
26
- const rounding: number = Utils.getRounding(injectMethod);
27
- return Math.round(value * rounding) / rounding;
28
- }
29
-
30
- public static isInRange(value: number | null, interval: IInterval): boolean {
31
- if (value === null) {
32
- return false;
33
- }
34
-
35
- return value >= interval.min && value <= interval.max;
36
- }
37
-
38
- public static convertBGLToMGDL(value: number): number {
39
- return Math.round(value * MGDL_PER_MMOLL_BGL);
40
- }
41
- public static displayedBGLValue(value: number, unit: BloodGlucoseUnit): number {
42
- return unit === BloodGlucoseUnit.MMOL_L ? value : Utils.convertBGLToMGDL(value);
43
- }
44
-
45
- public static convertBKLToMGDL(value: number): number {
46
- return Math.round(value * MGDL_PER_MMOLL_BKL);
47
- }
48
- public static displayedBKLValue(value: number, unit: BloodKetonesUnit): number {
49
- return unit === BloodKetonesUnit.MMOL_L ? value : Utils.convertBKLToMGDL(value);
50
- }
51
-
52
- public static formatUnit = (unit: BloodGlucoseUnit | BloodKetonesUnit): string => {
53
- const unitWithoutLastLetter = unit.substring(0, unit.length - 1);
54
- const lastLetterUppercase = unit.substring(unit.length - 1, unit.length).toUpperCase();
55
- return `${unitWithoutLastLetter}${lastLetterUppercase}`;
56
- };
57
- }