@hedia/recommendation-screen 1.0.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 (118) hide show
  1. package/.prettierignore +2 -0
  2. package/Changelog.md +5 -0
  3. package/README.md +3 -0
  4. package/android/app/BUCK +55 -0
  5. package/android/app/build.gradle +226 -0
  6. package/android/app/build_defs.bzl +19 -0
  7. package/android/app/debug.keystore +0 -0
  8. package/android/app/proguard-rules.pro +10 -0
  9. package/android/app/src/debug/AndroidManifest.xml +8 -0
  10. package/android/app/src/debug/java/com/hediarecommendationscreen/ReactNativeFlipper.java +72 -0
  11. package/android/app/src/main/AndroidManifest.xml +27 -0
  12. package/android/app/src/main/java/com/hediarecommendationscreen/MainActivity.java +15 -0
  13. package/android/app/src/main/java/com/hediarecommendationscreen/MainApplication.java +80 -0
  14. package/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  15. package/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  16. package/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  17. package/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  18. package/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  19. package/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  20. package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  21. package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  22. package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  23. package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  24. package/android/app/src/main/res/values/strings.xml +3 -0
  25. package/android/app/src/main/res/values/styles.xml +9 -0
  26. package/android/build.gradle +38 -0
  27. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  28. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  29. package/android/gradle.properties +28 -0
  30. package/android/gradlew +188 -0
  31. package/android/gradlew.bat +100 -0
  32. package/android/settings.gradle +3 -0
  33. package/index-git.sh +5 -0
  34. package/index.d.ts +5 -0
  35. package/index.js +16 -0
  36. package/index.ts +19 -0
  37. package/ios/HediaRecommendationScreen/AppDelegate.h +8 -0
  38. package/ios/HediaRecommendationScreen/AppDelegate.m +58 -0
  39. package/ios/HediaRecommendationScreen/Base.lproj/LaunchScreen.xib +42 -0
  40. package/ios/HediaRecommendationScreen/Images.xcassets/AppIcon.appiconset/Contents.json +38 -0
  41. package/ios/HediaRecommendationScreen/Images.xcassets/Contents.json +6 -0
  42. package/ios/HediaRecommendationScreen/Info.plist +57 -0
  43. package/ios/HediaRecommendationScreen/main.m +9 -0
  44. package/ios/HediaRecommendationScreen-tvOS/Info.plist +53 -0
  45. package/ios/HediaRecommendationScreen-tvOSTests/Info.plist +24 -0
  46. package/ios/HediaRecommendationScreen.xcodeproj/project.pbxproj +807 -0
  47. package/ios/HediaRecommendationScreen.xcodeproj/xcshareddata/xcschemes/HediaRecommendationScreen-tvOS.xcscheme +88 -0
  48. package/ios/HediaRecommendationScreen.xcodeproj/xcshareddata/xcschemes/HediaRecommendationScreen.xcscheme +88 -0
  49. package/ios/HediaRecommendationScreenTests/HediaRecommendationScreenTests.m +65 -0
  50. package/ios/HediaRecommendationScreenTests/Info.plist +24 -0
  51. package/ios/Podfile +104 -0
  52. package/package.json +75 -0
  53. package/src/RecommendationScreen.d.ts +42 -0
  54. package/src/RecommendationScreen.js +142 -0
  55. package/src/RecommendationScreen.tsx +210 -0
  56. package/src/assets/happy.png +0 -0
  57. package/src/assets/happy_active.png +0 -0
  58. package/src/assets/neutral.png +0 -0
  59. package/src/assets/neutral_active.png +0 -0
  60. package/src/assets/sad.png +0 -0
  61. package/src/assets/sad_active.png +0 -0
  62. package/src/assets/semi_happy.png +0 -0
  63. package/src/assets/semi_happy_active.png +0 -0
  64. package/src/assets/semi_sad.png +0 -0
  65. package/src/assets/semi_sad_active.png +0 -0
  66. package/src/components/Emotion.d.ts +14 -0
  67. package/src/components/Emotion.js +55 -0
  68. package/src/components/Emotion.tsx +71 -0
  69. package/src/components/Header.d.ts +52 -0
  70. package/src/components/Header.js +83 -0
  71. package/src/components/Header.tsx +94 -0
  72. package/src/components/Icon.js +41 -0
  73. package/src/components/InfoBars.d.ts +67 -0
  74. package/src/components/InfoBars.js +89 -0
  75. package/src/components/InfoBars.tsx +93 -0
  76. package/src/components/InvisibleNumberInput.d.ts +24 -0
  77. package/src/components/InvisibleNumberInput.js +64 -0
  78. package/src/components/InvisibleNumberInput.tsx +88 -0
  79. package/src/components/MoodIcon.d.ts +14 -0
  80. package/src/components/MoodIcon.js +53 -0
  81. package/src/components/MoodIcon.tsx +58 -0
  82. package/src/components/RecentInsulin.d.ts +9 -0
  83. package/src/components/RecentInsulin.js +91 -0
  84. package/src/components/RecentInsulin.tsx +97 -0
  85. package/src/components/RecommendedCarbs.d.ts +30 -0
  86. package/src/components/RecommendedCarbs.js +193 -0
  87. package/src/components/RecommendedCarbs.tsx +242 -0
  88. package/src/components/RecommendedInsulin.d.ts +22 -0
  89. package/src/components/RecommendedInsulin.js +110 -0
  90. package/src/components/RecommendedInsulin.tsx +147 -0
  91. package/src/components/Remeasure.d.ts +13 -0
  92. package/src/components/Remeasure.js +89 -0
  93. package/src/components/Remeasure.tsx +105 -0
  94. package/src/components/TransferToLogbook.d.ts +14 -0
  95. package/src/components/TransferToLogbook.js +81 -0
  96. package/src/components/TransferToLogbook.tsx +97 -0
  97. package/src/locale/da/messages.js +1 -0
  98. package/src/locale/da/messages.po +119 -0
  99. package/src/locale/en/messages.js +1 -0
  100. package/src/locale/en/messages.po +119 -0
  101. package/src/locale/i18nUtils.d.ts +5 -0
  102. package/src/locale/i18nUtils.js +22 -0
  103. package/src/locale/i18nUtils.ts +21 -0
  104. package/src/types/enum.d.ts +26 -0
  105. package/src/types/enum.js +34 -0
  106. package/src/types/enum.ts +30 -0
  107. package/src/types/types.d.ts +21 -0
  108. package/src/types/types.js +2 -0
  109. package/src/types/types.ts +23 -0
  110. package/src/utils/Constants.d.ts +3 -0
  111. package/src/utils/Constants.js +6 -0
  112. package/src/utils/Constants.ts +3 -0
  113. package/src/utils/RecommendationError.d.ts +9 -0
  114. package/src/utils/RecommendationError.js +17 -0
  115. package/src/utils/RecommendationError.ts +30 -0
  116. package/src/utils/Utils.d.ts +5 -0
  117. package/src/utils/Utils.js +24 -0
  118. package/src/utils/Utils.ts +26 -0
@@ -0,0 +1,210 @@
1
+ import React from "react";
2
+ import { ScrollView, StyleSheet, Text, View } from "react-native";
3
+ import { BGUnit, InjectionMethod, Languages, MoodEnum } from "./types/enum";
4
+ import { BACKGROUND_COLOUR_PURPLE, BORDER_COLOUR_TEAL, BORDER_COLOUR_WHITE } from "./utils/Constants";
5
+
6
+ import Header, { headerStyles } from "./components/Header";
7
+ import InfoBars, { infoStyles, IProps } from "./components/InfoBars";
8
+ import RecentInsulin from "./components/RecentInsulin";
9
+ import RecommendedCarbs from "./components/RecommendedCarbs";
10
+ import RecommendedInsulin from "./components/RecommendedInsulin";
11
+ import Remeasure from "./components/Remeasure";
12
+
13
+ import * as Calculator from "@hedia/recommendation-calculator";
14
+ import { t } from "@lingui/macro";
15
+ import { I18nProvider } from "@lingui/react";
16
+ import Emotion from "./components/Emotion";
17
+ import TransferToLogbook from "./components/TransferToLogbook";
18
+ import { RecommendationError } from "./utils/RecommendationError";
19
+
20
+ import { changeLanguage, i18n } from "./locale/i18nUtils";
21
+ import { Utils } from "./utils/Utils";
22
+
23
+ interface IResult {
24
+ suggested: number;
25
+ entered?: number;
26
+ }
27
+
28
+ export interface IRecommendationProps {
29
+ // Values
30
+ units: BGUnit;
31
+ language: Languages;
32
+
33
+ calculatorParams: Calculator.IRecommendationParams;
34
+ injectionMethod: InjectionMethod;
35
+
36
+ // Callbacks
37
+ exitCallback(): void;
38
+ removeRecommendedCarbs(): void;
39
+ onRecentInsulinYes(): void;
40
+
41
+ transferToLogbook(carbs: IResult, insulin: IResult, reminder: number): void;
42
+ onError(error: RecommendationError): void;
43
+ }
44
+
45
+ interface IState {
46
+ remeasureTime: number;
47
+ showRecentInsulin: boolean;
48
+ insulinRecommendation: number;
49
+ activityReduction?: number;
50
+ carbRecommendation: number;
51
+ activeInsulin: number;
52
+ selectedMood: MoodEnum | 0;
53
+ enteredCarbs?: number;
54
+ enteredInsulin?: number;
55
+ }
56
+
57
+ export default class RecommendationScreen extends React.Component<IRecommendationProps, IState> {
58
+ constructor(props: IRecommendationProps) {
59
+ super(props);
60
+
61
+ changeLanguage(props.language);
62
+
63
+ const { bolus, carbRecommendation, activityReduction } = Calculator.calculateRecommendation(
64
+ props.calculatorParams,
65
+ );
66
+ this.state = {
67
+ remeasureTime: 1.5,
68
+ showRecentInsulin: true,
69
+ insulinRecommendation: Utils.roundValue(bolus, props.injectionMethod),
70
+ activityReduction,
71
+ carbRecommendation,
72
+ activeInsulin: 0.0,
73
+ selectedMood: 0,
74
+ };
75
+ }
76
+
77
+ public updateRemeasureTime = (remeasureTime: number) => {
78
+ this.setState({
79
+ remeasureTime,
80
+ });
81
+ };
82
+
83
+ public handleNoRecentInsulin = () => {
84
+ this.setState({
85
+ showRecentInsulin: false,
86
+ });
87
+ };
88
+
89
+ public removeCarbRecommendation = () => {
90
+ this.setState({
91
+ enteredCarbs: null,
92
+ carbRecommendation: null,
93
+ });
94
+ this.props.removeRecommendedCarbs();
95
+ };
96
+
97
+ public handleMoodSelected = (selectedMood: IState["selectedMood"]) => {
98
+ this.setState({
99
+ selectedMood,
100
+ });
101
+ };
102
+
103
+ public updateCarbRecommendation = (enteredCarbs: number) => {
104
+ this.setState({
105
+ enteredCarbs,
106
+ });
107
+ };
108
+
109
+ public updateInsulinRecommendation = (enteredInsulin: number) => {
110
+ this.setState({
111
+ enteredInsulin,
112
+ });
113
+ };
114
+
115
+ public handleTransfer = () => {
116
+ this.props.transferToLogbook(
117
+ {
118
+ suggested: this.state.carbRecommendation,
119
+ entered: this.state.enteredCarbs,
120
+ },
121
+ {
122
+ suggested: this.state.insulinRecommendation,
123
+ entered: this.state.enteredInsulin,
124
+ },
125
+ this.state.remeasureTime,
126
+ );
127
+ };
128
+
129
+ public render() {
130
+ return (
131
+ <I18nProvider language={this.props.language} i18n={i18n}>
132
+ <ScrollView style={containerStyles.container}>
133
+ <Header exitCallback={this.props.exitCallback} />
134
+ <InfoBars
135
+ label={i18n._(t`Active Insulin`)}
136
+ value={`${this.state.activeInsulin}`}
137
+ units={i18n._(t`units`)}
138
+ showZeroAsDash={false}
139
+ />
140
+ <InfoBars
141
+ label={i18n._(t`Blood Glucose Level`)}
142
+ value={`${this.props.calculatorParams.currentBGL}`}
143
+ units={this.props.units}
144
+ showZeroAsDash={true}
145
+ />
146
+ <View style={containerStyles.calcContainer}>
147
+ <View style={containerStyles.calcMargin}>
148
+ <View
149
+ style={[
150
+ containerStyles.calcBorder,
151
+ {
152
+ borderColor: this.state.carbRecommendation
153
+ ? BORDER_COLOUR_TEAL
154
+ : BORDER_COLOUR_WHITE,
155
+ },
156
+ ]}
157
+ >
158
+ <RecommendedCarbs
159
+ enteredCarbs={`${this.props.calculatorParams.carbohydrates}`}
160
+ changedRecommendedCarbs={this.updateCarbRecommendation}
161
+ recommendedCarbs={`${this.state.enteredCarbs ?? this.state.carbRecommendation}`}
162
+ removeRecommendedCarbs={this.removeCarbRecommendation}
163
+ onError={this.props.onError}
164
+ />
165
+ <Remeasure
166
+ onSliderChange={this.updateRemeasureTime}
167
+ remeasureTime={this.state.remeasureTime}
168
+ />
169
+ </View>
170
+ </View>
171
+ </View>
172
+ {this.state.showRecentInsulin ? (
173
+ <RecentInsulin
174
+ onRecentInsulinYes={this.props.onRecentInsulinYes}
175
+ onRecentInsulinNo={this.handleNoRecentInsulin}
176
+ />
177
+ ) : (
178
+ <RecommendedInsulin
179
+ injectionMethod={this.props.injectionMethod}
180
+ insulinRecommendation={this.state.enteredInsulin ?? this.state.insulinRecommendation}
181
+ activityReduction={this.state.activityReduction}
182
+ updateRecommendedInsulin={this.updateInsulinRecommendation}
183
+ onError={this.props.onError}
184
+ />
185
+ )}
186
+ <Emotion moodSelected={this.handleMoodSelected} />
187
+ <TransferToLogbook visible={!this.state.showRecentInsulin} transfer={this.handleTransfer} />
188
+ </ScrollView>
189
+ </I18nProvider>
190
+ );
191
+ }
192
+ }
193
+
194
+ const containerStyles = StyleSheet.create({
195
+ container: {
196
+ flex: 1,
197
+ backgroundColor: BACKGROUND_COLOUR_PURPLE,
198
+ },
199
+ calcContainer: {
200
+ flex: 1,
201
+ },
202
+ calcMargin: {
203
+ flex: 1,
204
+ margin: headerStyles.margin.margin,
205
+ },
206
+ calcBorder: {
207
+ ...infoStyles.border,
208
+ borderColor: BORDER_COLOUR_TEAL,
209
+ },
210
+ });
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,14 @@
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 {};
@@ -0,0 +1,55 @@
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 macro_1 = require("@lingui/macro");
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const i18nUtils_1 = require("../locale/i18nUtils");
10
+ const enum_1 = require("../types/enum");
11
+ const MoodIcon_1 = __importDefault(require("./MoodIcon"));
12
+ class Emotion extends react_1.default.Component {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.state = {
16
+ selected: 0,
17
+ };
18
+ this.handleIconPress = (selected, toggle) => {
19
+ const select = toggle ? selected : 0;
20
+ this.setState({
21
+ selected: select,
22
+ });
23
+ this.props.moodSelected(select);
24
+ };
25
+ }
26
+ render() {
27
+ const values = Object.values(enum_1.MoodEnum).filter((val) => isNaN(Number(val)));
28
+ const mapped = values.map((key) => {
29
+ const moodValue = enum_1.MoodEnum[key];
30
+ return (<MoodIcon_1.default onPress={(toggle) => this.handleIconPress(moodValue, toggle)} active={moodValue === this.state.selected} mood={moodValue} key={moodValue}/>);
31
+ });
32
+ return (<react_native_1.View style={emotionStyles.container}>
33
+ <react_native_1.View style={emotionStyles.feelingContainer}>
34
+ <react_native_1.Text style={emotionStyles.feelingText}>{i18nUtils_1.i18n._(macro_1.t `How are you feeling?`)}</react_native_1.Text>
35
+ </react_native_1.View>
36
+ <react_native_1.View style={emotionStyles.moodIconContainer}>{mapped}</react_native_1.View>
37
+ </react_native_1.View>);
38
+ }
39
+ }
40
+ exports.default = Emotion;
41
+ const emotionStyles = react_native_1.StyleSheet.create({
42
+ container: {
43
+ flex: 1,
44
+ },
45
+ feelingContainer: {
46
+ marginVertical: `3%`,
47
+ },
48
+ feelingText: {
49
+ textAlign: `center`,
50
+ color: `white`,
51
+ fontWeight: `bold`,
52
+ fontSize: react_native_1.Dimensions.get(`screen`).width / 26,
53
+ },
54
+ moodIconContainer: { flex: 1, flexDirection: `row`, justifyContent: `center` },
55
+ });
@@ -0,0 +1,71 @@
1
+ import { t } from "@lingui/macro";
2
+ import React from "react";
3
+ import { Dimensions, Image, StyleSheet, Text, View } from "react-native";
4
+ import { i18n } from "../locale/i18nUtils";
5
+ import { MoodEnum } from "../types/enum";
6
+ import MoodIcon from "./MoodIcon";
7
+
8
+ interface IProps {
9
+ moodSelected(mood: MoodEnum | 0): void;
10
+ }
11
+
12
+ type value = keyof typeof MoodEnum;
13
+
14
+ interface IState {
15
+ selected: MoodEnum | 0;
16
+ }
17
+
18
+ export default class Emotion extends React.Component<IProps, IState> {
19
+ public state: IState = {
20
+ selected: 0,
21
+ };
22
+
23
+ public handleIconPress = (selected: number, toggle: boolean) => {
24
+ const select = toggle ? selected : 0;
25
+ this.setState({
26
+ selected: select,
27
+ });
28
+ this.props.moodSelected(select);
29
+ };
30
+
31
+ public render() {
32
+ const values = Object.values(MoodEnum).filter((val) => isNaN(Number(val))) as Array<value>;
33
+
34
+ const mapped = values.map((key) => {
35
+ const moodValue = MoodEnum[key];
36
+ return (
37
+ <MoodIcon
38
+ onPress={(toggle) => this.handleIconPress(moodValue, toggle)}
39
+ active={moodValue === this.state.selected}
40
+ mood={moodValue}
41
+ key={moodValue}
42
+ />
43
+ );
44
+ });
45
+
46
+ return (
47
+ <View style={emotionStyles.container}>
48
+ <View style={emotionStyles.feelingContainer}>
49
+ <Text style={emotionStyles.feelingText}>{i18n._(t`How are you feeling?`)}</Text>
50
+ </View>
51
+ <View style={emotionStyles.moodIconContainer}>{mapped}</View>
52
+ </View>
53
+ );
54
+ }
55
+ }
56
+
57
+ const emotionStyles = StyleSheet.create({
58
+ container: {
59
+ flex: 1,
60
+ },
61
+ feelingContainer: {
62
+ marginVertical: `3%`,
63
+ },
64
+ feelingText: {
65
+ textAlign: `center`,
66
+ color: `white`,
67
+ fontWeight: `bold`,
68
+ fontSize: Dimensions.get(`screen`).width / 26,
69
+ },
70
+ moodIconContainer: { flex: 1, flexDirection: `row`, justifyContent: `center` },
71
+ });
@@ -0,0 +1,52 @@
1
+ import React from "react";
2
+ import { IRecommendationProps } from "../RecommendationScreen";
3
+ interface IProps {
4
+ exitCallback: IRecommendationProps["exitCallback"];
5
+ }
6
+ interface IState {
7
+ hello: string;
8
+ }
9
+ export default class Header extends React.Component<IProps, IState> {
10
+ state: IState;
11
+ render(): JSX.Element;
12
+ }
13
+ export declare const headerStyles: {
14
+ backgroundColour: {
15
+ backgroundColor: string;
16
+ };
17
+ margin: {
18
+ margin: string;
19
+ flexDirection: "row";
20
+ flex: number;
21
+ };
22
+ headerContainer: {
23
+ flexDirection: "row";
24
+ flex: number;
25
+ };
26
+ exitButtonContainer: {
27
+ flex: number;
28
+ };
29
+ exitButton: {
30
+ flex: number;
31
+ };
32
+ iconStyle: {
33
+ fontSize: number;
34
+ color: string;
35
+ };
36
+ headerTextContainer: {
37
+ flex: number;
38
+ justifyContent: "center";
39
+ alignItems: "center";
40
+ marginTop: string;
41
+ };
42
+ headerText: {
43
+ fontSize: number;
44
+ fontWeight: "bold";
45
+ textAlign: "center";
46
+ color: string;
47
+ };
48
+ headerFiller: {
49
+ flex: number;
50
+ };
51
+ };
52
+ export {};
@@ -0,0 +1,83 @@
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.headerStyles = void 0;
7
+ const macro_1 = require("@lingui/macro");
8
+ const react_1 = __importDefault(require("react"));
9
+ const react_native_1 = require("react-native");
10
+ const i18nUtils_1 = require("../locale/i18nUtils");
11
+ const Constants_1 = require("../utils/Constants");
12
+ const Icon_1 = __importDefault(require("./Icon"));
13
+ class Header extends react_1.default.Component {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.state = {
17
+ hello: `World`,
18
+ };
19
+ }
20
+ render() {
21
+ return (<react_1.default.Fragment>
22
+ <react_native_1.SafeAreaView style={exports.headerStyles.backgroundColour}/>
23
+ <react_native_1.View style={exports.headerStyles.headerContainer}>
24
+ <react_native_1.View style={exports.headerStyles.margin}>
25
+ <react_native_1.View style={exports.headerStyles.exitButtonContainer}>
26
+ <react_native_1.View style={exports.headerStyles.exitButton}>
27
+ <react_native_1.TouchableOpacity accessibilityLabel="exitButton" style={exports.headerStyles.exitButton} onPress={this.props.exitCallback}>
28
+ <Icon_1.default iconIdentifier={`Ionicons/ios-close-circle-outline`} style={exports.headerStyles.iconStyle}/>
29
+ </react_native_1.TouchableOpacity>
30
+ <react_native_1.View style={exports.headerStyles.headerFiller}/>
31
+ </react_native_1.View>
32
+ </react_native_1.View>
33
+ <react_native_1.View style={exports.headerStyles.headerTextContainer}>
34
+ <react_native_1.Text style={exports.headerStyles.headerText} testID="headerText">
35
+ {i18nUtils_1.i18n._(macro_1.t `INSULIN\nRECOMMENDATION`)}
36
+ </react_native_1.Text>
37
+ </react_native_1.View>
38
+ <react_native_1.View style={exports.headerStyles.headerFiller}/>
39
+ </react_native_1.View>
40
+ </react_native_1.View>
41
+ </react_1.default.Fragment>);
42
+ }
43
+ }
44
+ exports.default = Header;
45
+ exports.headerStyles = react_native_1.StyleSheet.create({
46
+ backgroundColour: {
47
+ backgroundColor: Constants_1.BACKGROUND_COLOUR_PURPLE,
48
+ },
49
+ margin: {
50
+ margin: `3%`,
51
+ flexDirection: `row`,
52
+ flex: 1,
53
+ },
54
+ headerContainer: {
55
+ flexDirection: `row`,
56
+ flex: 1,
57
+ },
58
+ exitButtonContainer: {
59
+ flex: 1,
60
+ },
61
+ exitButton: {
62
+ flex: 1,
63
+ },
64
+ iconStyle: {
65
+ fontSize: react_native_1.Dimensions.get(`screen`).width / 10,
66
+ color: Constants_1.BORDER_COLOUR_WHITE,
67
+ },
68
+ headerTextContainer: {
69
+ flex: 5,
70
+ justifyContent: `center`,
71
+ alignItems: `center`,
72
+ marginTop: `5%`,
73
+ },
74
+ headerText: {
75
+ fontSize: react_native_1.Dimensions.get(`screen`).width / 14,
76
+ fontWeight: `bold`,
77
+ textAlign: `center`,
78
+ color: `white`,
79
+ },
80
+ headerFiller: {
81
+ flex: 1,
82
+ },
83
+ });
@@ -0,0 +1,94 @@
1
+ import { t } from "@lingui/macro";
2
+ import React from "react";
3
+ import { Dimensions, SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
4
+ import { i18n } from "../locale/i18nUtils";
5
+ import { IRecommendationProps } from "../RecommendationScreen";
6
+ import { BACKGROUND_COLOUR_PURPLE, BORDER_COLOUR_WHITE } from "../utils/Constants";
7
+ import Icon from "./Icon";
8
+
9
+ interface IProps {
10
+ exitCallback: IRecommendationProps["exitCallback"];
11
+ }
12
+
13
+ interface IState {
14
+ hello: string;
15
+ }
16
+
17
+ export default class Header extends React.Component<IProps, IState> {
18
+ public state: IState = {
19
+ hello: `World`,
20
+ };
21
+
22
+ public render() {
23
+ return (
24
+ <React.Fragment>
25
+ <SafeAreaView style={headerStyles.backgroundColour} />
26
+ <View style={headerStyles.headerContainer}>
27
+ <View style={headerStyles.margin}>
28
+ <View style={headerStyles.exitButtonContainer}>
29
+ <View style={headerStyles.exitButton}>
30
+ <TouchableOpacity
31
+ accessibilityLabel="exitButton"
32
+ style={headerStyles.exitButton}
33
+ onPress={this.props.exitCallback}
34
+ >
35
+ <Icon
36
+ iconIdentifier={`Ionicons/ios-close-circle-outline`}
37
+ style={headerStyles.iconStyle}
38
+ />
39
+ </TouchableOpacity>
40
+ <View style={headerStyles.headerFiller} />
41
+ </View>
42
+ </View>
43
+ <View style={headerStyles.headerTextContainer}>
44
+ <Text style={headerStyles.headerText} testID="headerText">
45
+ {i18n._(t`INSULIN\nRECOMMENDATION`)}
46
+ </Text>
47
+ </View>
48
+ <View style={headerStyles.headerFiller} />
49
+ </View>
50
+ </View>
51
+ </React.Fragment>
52
+ );
53
+ }
54
+ }
55
+
56
+ export const headerStyles = StyleSheet.create({
57
+ backgroundColour: {
58
+ backgroundColor: BACKGROUND_COLOUR_PURPLE,
59
+ },
60
+ margin: {
61
+ margin: `3%`,
62
+ flexDirection: `row`,
63
+ flex: 1,
64
+ },
65
+ headerContainer: {
66
+ flexDirection: `row`,
67
+ flex: 1,
68
+ },
69
+ exitButtonContainer: {
70
+ flex: 1,
71
+ },
72
+ exitButton: {
73
+ flex: 1,
74
+ },
75
+ iconStyle: {
76
+ fontSize: Dimensions.get(`screen`).width / 10,
77
+ color: BORDER_COLOUR_WHITE,
78
+ },
79
+ headerTextContainer: {
80
+ flex: 5,
81
+ justifyContent: `center`,
82
+ alignItems: `center`,
83
+ marginTop: `5%`,
84
+ },
85
+ headerText: {
86
+ fontSize: Dimensions.get(`screen`).width / 14,
87
+ fontWeight: `bold`,
88
+ textAlign: `center`,
89
+ color: `white`,
90
+ },
91
+ headerFiller: {
92
+ flex: 1,
93
+ },
94
+ });
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+
3
+ const IconSets = {
4
+ AntDesign: require(`react-native-vector-icons/AntDesign`),
5
+ Feather: require(`react-native-vector-icons/Feather`),
6
+ EvilIcons: require(`react-native-vector-icons/EvilIcons`),
7
+ Ionicons: require(`react-native-vector-icons/Ionicons`),
8
+ FontAwesome: require(`react-native-vector-icons/FontAwesome`),
9
+ Entypo: require(`react-native-vector-icons/Entypo`),
10
+ };
11
+
12
+ export default class Icon extends React.Component {
13
+ setNativeProps(nativeProps) {
14
+ this._root.setNativeProps(nativeProps);
15
+ }
16
+
17
+ render() {
18
+ const iconParts = this.props.iconIdentifier.split(`/`);
19
+ let iconPackageName = iconParts[0];
20
+ let iconName = iconParts[1];
21
+ if (!IconSets[iconPackageName]) {
22
+ iconPackageName = `FontAwesome`;
23
+ iconName = `question`;
24
+ }
25
+ const IconClass = IconSets[iconPackageName].default;
26
+ const clonedProps = { ...this.props, name: iconName };
27
+ delete clonedProps.iconIdentifier;
28
+
29
+ // Support FontAwesome5's solid/light/brand
30
+ if (clonedProps.iconStyle) {
31
+ clonedProps[clonedProps.iconStyle] = true;
32
+ }
33
+ delete clonedProps.iconStyle;
34
+
35
+ return <IconClass {...clonedProps} ref={(component) => (this._root = component)} />;
36
+ }
37
+ }
38
+
39
+ Icon.defaultProps = {
40
+ iconIdentifier: `FontAwesome/question`,
41
+ };