@olea-bps/components 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 (79) hide show
  1. package/AppBar/index.js +83 -0
  2. package/AppBar/styles.js +27 -0
  3. package/BookDetail/index.js +268 -0
  4. package/BookDetail/styles.js +124 -0
  5. package/Component/342/200/216JobsFilter/index.js +188 -0
  6. package/Component/342/200/216JobsFilter/styles.js +12 -0
  7. package/ConnectivityWarning/index.js +65 -0
  8. package/ConnectivityWarning/styles.js +19 -0
  9. package/ContactDetail/index.js +232 -0
  10. package/ContactDetail/styles.js +32 -0
  11. package/CourseDetail/index.js +357 -0
  12. package/CourseDetail/styles.js +59 -0
  13. package/CourseDetailDialog/index.js +169 -0
  14. package/CourseDetailDialog/styles.js +116 -0
  15. package/CourseInfo/index.js +219 -0
  16. package/CourseInfo/styles.js +40 -0
  17. package/DevelopmentDialog/index.js +208 -0
  18. package/DevelopmentDialog/styles.js +10 -0
  19. package/EventCodeInput/index.js +146 -0
  20. package/EventCodeInput/styles.js +108 -0
  21. package/FlexMenuEntry/index.js +84 -0
  22. package/FlexMenuEntry/styles.js +27 -0
  23. package/MainMenuEntry/index.js +88 -0
  24. package/MainMenuEntry/styles.js +28 -0
  25. package/MealItem/index.js +87 -0
  26. package/MealItem/styles.js +73 -0
  27. package/MensaMenu/index.js +307 -0
  28. package/MensaMenu/styles.js +94 -0
  29. package/MensaSlider/index.js +184 -0
  30. package/MensaSlider/styles.js +53 -0
  31. package/Modal/index.js +106 -0
  32. package/Modal/styles.js +8 -0
  33. package/NewsDetail/index.js +377 -0
  34. package/NewsDetail/styles.js +77 -0
  35. package/NewsList/index.js +120 -0
  36. package/NewsList/styles.js +19 -0
  37. package/NewsListItem/index.js +89 -0
  38. package/NewsListItem/styles.js +32 -0
  39. package/OtherCourses/index.js +152 -0
  40. package/OtherCourses/styles.js +10 -0
  41. package/PtsDeparture/index.js +140 -0
  42. package/PtsDeparture/styles.js +7 -0
  43. package/PtsStation/index.js +183 -0
  44. package/PtsStation/styles.js +47 -0
  45. package/QuickLinks/index.js +127 -0
  46. package/QuickLinks/styles.js +45 -0
  47. package/RoomDetail/index.js +281 -0
  48. package/RoomDetail/styles.js +56 -0
  49. package/ScaledImage/index.js +92 -0
  50. package/SearchResults/index.js +362 -0
  51. package/SearchResults/styles.js +59 -0
  52. package/SettingSection/index.js +54 -0
  53. package/SettingSection/styles.js +15 -0
  54. package/SettingsDialog/index.js +52 -0
  55. package/SettingsDialog/styles.js +12 -0
  56. package/SettingsDialogRadio/index.js +66 -0
  57. package/SettingsDialogRadio/styles.js +7 -0
  58. package/SettingsDialogSelect/index.js +73 -0
  59. package/SettingsDialogSelect/styles.js +7 -0
  60. package/TimetableCodeInput/index.js +201 -0
  61. package/TimetableCodeInput/styles.js +28 -0
  62. package/TimetableDay/index.js +266 -0
  63. package/TimetableDay/styles.js +103 -0
  64. package/TimetableEvent/index.js +163 -0
  65. package/TimetableEvent/styles.js +108 -0
  66. package/TimetableList/index.js +116 -0
  67. package/TimetableList/styles.js +109 -0
  68. package/TimetableMonth/index.js +156 -0
  69. package/TimetableMonth/styles.js +29 -0
  70. package/TimetableWeek/index.js +245 -0
  71. package/TimetableWeek/styles.js +58 -0
  72. package/TopNews/index.js +282 -0
  73. package/TopNews/styles.js +125 -0
  74. package/TopNewsHtwk/index.js +279 -0
  75. package/TopNewsHtwk/styles.js +142 -0
  76. package/WebView/index.js +108 -0
  77. package/WebView/styles.js +11 -0
  78. package/index.js +39 -0
  79. package/package.json +37 -0
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import React from 'react';
16
+ import PropTypes from 'prop-types';
17
+
18
+ import {
19
+ StyleSheet, Text, FlatList, View, TouchableOpacity
20
+ } from 'react-native';
21
+ import {withTheme} from "react-native-paper";
22
+ import {withTranslation} from "react-i18next";
23
+ import { connect } from 'react-redux'
24
+
25
+ import merge from 'lodash/merge';
26
+ import unescape from 'lodash/unescape';
27
+ import {store} from '@olea-bps/core';
28
+
29
+
30
+ import componentStyles from "./styles"
31
+ import IconsOpenasist from "@olea-bps/icons-openasist";
32
+ import { BookDetail as BookDetailComponent } from '@olea-bps/components';
33
+ import { ContactDetail as ContactDetailComponent } from '@olea-bps/components';
34
+ import { RoomDetail as RoomDetailComponent } from '@olea-bps/components';
35
+ import { NewsDetail as NewsDetailComponent } from '@olea-bps/components';
36
+ import {handleHtmlEntities} from "@olea-bps/core/helper/format.helper";
37
+
38
+
39
+
40
+ class SearchResultsComponent extends React.Component {
41
+ static propTypes = {
42
+ type: PropTypes.string.isRequired
43
+ };
44
+
45
+ // Styles of this component
46
+ styles;
47
+
48
+ resultTypes = {
49
+ all: 'all',
50
+ books: 'books',
51
+ contacts: 'contacts',
52
+ rooms: 'rooms',
53
+ news: 'news',
54
+ };
55
+
56
+
57
+ constructor(props) {
58
+ super(props);
59
+ this.state = {
60
+ inProgress: true
61
+ };
62
+ // ------------------------------------------------------------------------
63
+ // PLUGIN FUNCTIONALITY
64
+ // ------------------------------------------------------------------------
65
+
66
+ const { pluginStyles,theme } = this.props;
67
+ this.styles = componentStyles(theme);
68
+
69
+ if(pluginStyles) {
70
+ this.styles = merge(componentStyles, pluginStyles);
71
+ }
72
+
73
+ this.styles = StyleSheet.create(this.styles);
74
+
75
+ // ------------------------------------------------------------------------
76
+ };
77
+
78
+ /**
79
+ * User pressed a card
80
+ *
81
+ * @param type
82
+ * @param item
83
+ * @private
84
+ */
85
+ _onCardPress = (type, item) => {
86
+ let content = null;
87
+
88
+ // Never provide props directly if you are using translations in this or a parent component
89
+ const props = {navigation: {...this.props.navigation}};
90
+ switch (type) {
91
+ case 'books':
92
+ content = (<BookDetailComponent {...props} book={item}/>);
93
+ break;
94
+ case 'contacts':
95
+ content = (<ContactDetailComponent {...props} contact={item}/>);
96
+ break;
97
+ case 'rooms':
98
+ content = (<RoomDetailComponent {...props} room={item}/>);
99
+ break;
100
+ case 'news':
101
+ content = (<NewsDetailComponent {...props} news={item}/>);
102
+ break;
103
+ }
104
+
105
+ store.dispatch({
106
+ type: 'UPDATE_MODAL_CONTENT',
107
+ modalContent: (
108
+ <View style={this.styles.modalContainer}>
109
+ {content}
110
+ </View>
111
+ )
112
+ });
113
+ this.props.navigation.navigate('Modal');
114
+ };
115
+
116
+ /**
117
+ * Render a card for a result item
118
+ *
119
+ * @param item
120
+ * @returns {*}
121
+ * @private
122
+ */
123
+ _renderResult = ({item, index}) => {
124
+ const {colors, themeStyles} = this.props.theme;
125
+ const { t } = this.props;
126
+
127
+ let borderColor = colors.messages.iconDefault;
128
+ let icon = 'book';
129
+ let key = 0;
130
+ let title = '';
131
+ let subtitle = '';
132
+ let type = this.resultTypes.books;
133
+
134
+ if(!item) {
135
+ return null;
136
+ }
137
+
138
+ // Books
139
+ if(item.bookId) {
140
+ borderColor = (item.available) ? colors.messages.successBackground : colors.messages.errorBackground;
141
+ icon = 'book';
142
+ key = item.bookId;
143
+ title = unescape(item.title);
144
+ subtitle = `${item.format || ''}${item.format && item.available ? ' | ' : ''}${item.available ? t('books:available') : t('books:notAvailable')}`;
145
+
146
+
147
+ // Contacts
148
+ } else if(item.firstName && item.lastName) {
149
+ borderColor = colors.messages.iconDefault;
150
+ icon = 'profile';
151
+ key = `${item.firstName} ${item.lastName}_${index}`;
152
+ title = unescape(`${item.firstName} ${item.lastName}`);
153
+ subtitle = item.department;
154
+ type = this.resultTypes.contacts
155
+
156
+ // Rooms
157
+ } else if(item.code2017) {
158
+ borderColor = colors.primary;
159
+ icon = 'map-search';
160
+ key = item.code2017;
161
+ //title = unescape(item.code2017);
162
+ title = unescape(item.title);
163
+ subtitle = unescape(`${item.building.postaladdress} ${item.building.name}`);
164
+ type = this.resultTypes.rooms
165
+
166
+ } else if(item.building && item.building.code) {
167
+ borderColor = colors.primary;
168
+ icon = 'map-search';
169
+ key = item.building.code
170
+ title = unescape(item.title);
171
+ subtitle = unescape(`${item.building.postaladdress} ${item.building.name} (Gebäude: ${item.building.code})`);
172
+ type = this.resultTypes.rooms
173
+
174
+ // News
175
+ } else if(item.author) {
176
+ borderColor = colors.black;
177
+ icon = 'news';
178
+ key = item.title;
179
+ title = unescape(item.title);
180
+ subtitle = unescape(item.pubdate);
181
+ type = this.resultTypes.news
182
+ }
183
+
184
+ return (
185
+ <TouchableOpacity key={key}
186
+ style={[themeStyles.card, {borderLeftWidth: 5, borderLeftColor: borderColor}]}
187
+ onPress={() => this._onCardPress(type, item)}
188
+ >
189
+ <View style={themeStyles.cardLeftIcon}>
190
+ <IconsOpenasist icon={icon} size={35} color={colors.messages.iconDefault} />
191
+ </View>
192
+ <View style={themeStyles.cardContent}>
193
+ <Text style={themeStyles.cardTitle}>{this._getShortTitle(title)}</Text>
194
+ <Text style={themeStyles.cardSubTitle}>{subtitle}</Text>
195
+ </View>
196
+ <View style={themeStyles.cardRightIcon}>
197
+ <IconsOpenasist icon={"forward"} size={25} color={colors.icon} />
198
+ </View>
199
+ </TouchableOpacity>
200
+ );
201
+ };
202
+
203
+ _keyExtractor = (item, index) => {
204
+ if(!item) {
205
+ return 'key_' + index;
206
+ }
207
+
208
+ return ((item.bookId) ? item.bookId : ((item.email) ? item.email + '_' + index : 'key_' + index));
209
+ };
210
+
211
+
212
+ /**
213
+ * Prevent titles with more than 3 lines
214
+ *
215
+ * @param title
216
+ * @returns {string|*}
217
+ * @private
218
+ */
219
+ _getShortTitle = (title) => {
220
+
221
+ // Handle html entities
222
+ title = handleHtmlEntities(title);
223
+ title = title.replace(/<(?:.|\n)*?>/gm, '');
224
+ if(title.length > 60) {
225
+ return title.slice(0, 55) + ' ... ';
226
+ } else {
227
+ return title;
228
+ }
229
+ };
230
+
231
+ render() {
232
+ // ------------------------------------------------------------------------
233
+ // PLUGIN FUNCTIONALITY
234
+ // ------------------------------------------------------------------------
235
+ const PluginComponent = this.props.pluginComponent;
236
+ if (PluginComponent) {
237
+ return <PluginComponent />;
238
+ }
239
+ // ------------------------------------------------------------------------
240
+
241
+ const { type, t } = this.props;
242
+ const {paddings, colors} = this.props.theme;
243
+ let output = [];
244
+ let results = [];
245
+
246
+ // Append books
247
+ if(type === this.resultTypes.all || type === this.resultTypes.books) {
248
+ if(results && results.length > 0) {
249
+ results = results.concat(this.props.searchResults.books);
250
+ } else {
251
+ results = this.props.searchResults.books;
252
+ }
253
+ }
254
+
255
+ // Append contacts
256
+ if(type === this.resultTypes.all || type === this.resultTypes.contacts) {
257
+ if(results && results.length > 0) {
258
+ results = results.concat(this.props.searchResults.contacts);
259
+ } else {
260
+ results = this.props.searchResults.contacts;
261
+ }
262
+ }
263
+
264
+ // Append rooms
265
+ if(type === this.resultTypes.all || type === this.resultTypes.rooms) {
266
+ if(results && results.length > 0) {
267
+ results = results.concat(this.props.searchResults.rooms);
268
+ } else {
269
+ results = this.props.searchResults.rooms;
270
+ }
271
+ }
272
+
273
+
274
+ // Append news
275
+ if(type === this.resultTypes.all || type === this.resultTypes.news) {
276
+ if(results && results.length > 0) {
277
+ results = results.concat(this.props.searchResults.news);
278
+ } else {
279
+ results = this.props.searchResults.news;
280
+ }
281
+ }
282
+
283
+
284
+ // Sorting results
285
+ if (results && results.length > 0) {
286
+ results.sort((itemA, itemB) => {
287
+ let itemAContainsSearchString = false;
288
+ let itemBContainsSearchString = false;
289
+ if (itemA && (
290
+ itemA.bookId && itemA.title.includes(this.props.searchString) ||
291
+ itemA.firstName && (
292
+ unescape(itemA.title).includes(this.props.searchString) ||
293
+ unescape(itemA.firstName + ' ' + itemA.lastName).includes(this.props.searchString) ||
294
+ itemA.department.includes(this.props.searchString)
295
+ ) ||
296
+ itemA.code2017 &&
297
+ (
298
+ unescape(itemA.code2017 + ' - ' + itemA.building.name).includes(this.props.searchString) ||
299
+ (itemA.codeDez1 + ' ' + itemA.codeURZ).includes(this.props.searchString)
300
+ )
301
+ )) {
302
+ itemAContainsSearchString = true;
303
+ }
304
+ if (itemB && (
305
+ itemB.bookId && itemB.title.includes(this.props.searchString) ||
306
+ itemB.firstName && (
307
+ unescape(itemB.title).includes(this.props.searchString) ||
308
+ unescape(itemB.firstName + ' ' + itemB.lastName).includes(this.props.searchString) ||
309
+ itemB.department.includes(this.props.searchString)
310
+ ) ||
311
+ itemB.code2017 &&
312
+ (
313
+ unescape(itemB.code2017 + ' - ' + itemB.building.name).includes(this.props.searchString) ||
314
+ (itemB.codeDez1 + ' ' + itemB.codeURZ).includes(this.props.searchString)
315
+ )
316
+ )) {
317
+ itemBContainsSearchString = true;
318
+ }
319
+ return itemBContainsSearchString - itemAContainsSearchString;
320
+ });
321
+ }
322
+
323
+ //No search results
324
+ if((type === this.resultTypes.all && (results === 0 || results === null)) ||
325
+ (type === this.resultTypes.books && (this.props.searchResults.books === null || this.props.searchResults.books.length === 0)) ||
326
+ (type === this.resultTypes.contacts &&(this.props.searchResults.contacts === null || this.props.searchResults.contacts.length === 0)) ||
327
+ (type === this.resultTypes.rooms &&(this.props.searchResults.rooms === null || this.props.searchResults.rooms.length === 0))) {
328
+ return (
329
+ <View style={[this.styles.containerInner, this.styles.containerErrorMsg]}>
330
+ <IconsOpenasist icon={"search"} size={48} color={colors.primary}/>
331
+ <Text style={this.styles.title}>{t('search:noResultsTitle')}</Text>
332
+ <Text style={this.styles.subtitle}>{t('search:noResultsSubtitle')}</Text>
333
+ </View>
334
+ );
335
+ } else {
336
+ return (
337
+ <FlatList
338
+ data={results}
339
+ extraData={this.state}
340
+ keyExtractor={this._keyExtractor}
341
+ renderItem={this._renderResult}
342
+ initialNumToRender={8}
343
+ getItemLayout={(data, index) => (
344
+ {length: 50, offset: 50 * index, index}
345
+ )}
346
+ contentContainerStyle={{paddingBottom: paddings.default}}
347
+ />
348
+ );
349
+ }
350
+ }
351
+ }
352
+
353
+ const mapStateToProps = state => {
354
+ return {
355
+ pluginComponent: state.pluginReducer.searchResults.component,
356
+ pluginStyles: state.pluginReducer.searchResults.styles,
357
+ searchResults: state.stateReducer.searchResults,
358
+ searchString: state.stateReducer.searchTopic
359
+ };
360
+ };
361
+
362
+ export default connect(mapStateToProps, null)(withTranslation()(withTheme(SearchResultsComponent)))
@@ -0,0 +1,59 @@
1
+ export default function(theme) {
2
+ return {
3
+ container: {
4
+ flex: 1
5
+ },
6
+ tabs: {
7
+ backgroundColor: theme.colors.primary
8
+ },
9
+ tab: {
10
+ ...theme.fonts.medium
11
+ },
12
+ tabIndicator: {
13
+ backgroundColor: theme.colors.tabs.tabIndicator,
14
+ height: 5
15
+ },
16
+ searchBar: {
17
+ borderRadius: 0,
18
+ height: 55
19
+ },
20
+ resultsContainer: {
21
+
22
+ },
23
+ activity: {
24
+ marginTop: theme.paddings.default
25
+ },
26
+ modalContainer: {
27
+ flex: 1,
28
+ //paddingTop: 50
29
+ },
30
+ modalContainerInner: {
31
+ flex: 1,
32
+ paddingHorizontal: 20,
33
+ paddingVertical: 20
34
+ },
35
+ containerErrorMsg: {
36
+ flex: 1,
37
+ justifyContent: 'center',
38
+ alignContent: 'center',
39
+ alignItems: 'center',
40
+ margin: theme.paddings.default
41
+ },
42
+ title : {
43
+ fontSize: theme.fontSizes.title,
44
+ color: theme.colors.text,
45
+ textAlign: 'center',
46
+ marginTop: theme.paddings.default,
47
+ marginLeft: theme.paddings.default,
48
+ marginRight: theme.paddings.default
49
+ },
50
+ subtitle : {
51
+ fontSize: theme.fontSizes.subtitle,
52
+ color: theme.colors.subtitle,
53
+ textAlign: 'center',
54
+ marginTop: theme.paddings.default,
55
+ marginLeft: theme.paddings.default,
56
+ marginRight: theme.paddings.default
57
+ }
58
+ }
59
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import React, { useMemo } from 'react';
16
+ import { StyleSheet } from 'react-native';
17
+
18
+ import { Button, List, useTheme } from 'react-native-paper';
19
+ import { useTranslation } from 'react-i18next';
20
+
21
+ import componentStyles from './styles';
22
+
23
+ export default function SettingSection({ title, description, onPress }) {
24
+ const { t } = useTranslation();
25
+ const theme = useTheme();
26
+
27
+ const { colors } = theme;
28
+
29
+ const styles = useMemo(
30
+ () => StyleSheet.create(componentStyles(theme)),
31
+ [theme, componentStyles]
32
+ )
33
+
34
+ return (
35
+ <List.Section>
36
+ <List.Item
37
+ accessible={false}
38
+ title={title}
39
+ description={description}
40
+ titleNumberOfLines={2}
41
+ titleStyle={styles.listItemTitle}
42
+ descriptionStyle={styles.listItemDescription}
43
+ right={() => (
44
+ <Button
45
+ labelStyle={styles.buttonLabel}
46
+ onPress={onPress}
47
+ color={colors.buttonText}
48
+ >
49
+ {t("common:changeLabel")}
50
+ </Button>
51
+ )}
52
+ />
53
+ </List.Section>);
54
+ }
@@ -0,0 +1,15 @@
1
+ export default function (theme) {
2
+ return {
3
+ title: {
4
+ fontSize: theme.fontSizes.l
5
+ },
6
+ description: {
7
+ fontSize: theme.fontSizes.m,
8
+ color: theme.colors.textLighter
9
+ },
10
+ buttonLabel: {
11
+ fontSize: theme.fontSizes.m,
12
+ color: theme.colors.text,
13
+ },
14
+ }
15
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import React, { useMemo } from 'react';
16
+ import { StyleSheet } from 'react-native';
17
+
18
+ import { Button, Dialog, Portal, useTheme } from 'react-native-paper';
19
+ import { useTranslation } from 'react-i18next';
20
+
21
+ import componentStyles from './styles';
22
+
23
+ export default function SettingsDialog({ children, title, visible, onDismiss, onOk }) {
24
+ const { t } = useTranslation();
25
+ const theme = useTheme();
26
+
27
+ const styles = useMemo(
28
+ () => StyleSheet.create(componentStyles(theme)),
29
+ [theme, componentStyles]
30
+ )
31
+
32
+ return (
33
+ <Portal>
34
+ <Dialog visible={visible} onDismiss={onDismiss}>
35
+ <Dialog.Title style={styles.title}>
36
+ {title}
37
+ </Dialog.Title>
38
+ <Dialog.Content>
39
+ {children}
40
+ </Dialog.Content>
41
+ <Dialog.Actions>
42
+ <Button
43
+ labelStyle={styles.okButton}
44
+ onPress={onOk}
45
+ >
46
+ {t("common:okLabel")}
47
+ </Button>
48
+ </Dialog.Actions>
49
+ </Dialog>
50
+ </Portal>
51
+ );
52
+ }
@@ -0,0 +1,12 @@
1
+ export default function (theme) {
2
+ return {
3
+ title: {
4
+ fontSize: theme.fontSizes.l,
5
+ lineHeight: theme.lineHeights.xxl
6
+ },
7
+ okButton: {
8
+ fontSize: theme.fontSizes.m,
9
+ color: theme.colors.buttonText,
10
+ },
11
+ }
12
+ };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import React, { useMemo } from 'react';
16
+ import { StyleSheet } from 'react-native';
17
+
18
+ import { RadioButton, useTheme } from 'react-native-paper';
19
+ import { useTranslation } from 'react-i18next';
20
+
21
+ import { SettingsDialog } from '@olea-bps/components';
22
+
23
+ import componentStyles from './styles';
24
+
25
+ export default function SettingsDialogRadio({ title, visible, options, selectedOption, onDismiss, onOk, onChange }) {
26
+ const { t } = useTranslation();
27
+ const theme = useTheme();
28
+
29
+ const styles = useMemo(
30
+ () => StyleSheet.create(componentStyles(theme)),
31
+ [theme, componentStyles]
32
+ )
33
+
34
+ return (
35
+ <SettingsDialog
36
+ title={title}
37
+ visible={visible}
38
+ onDismiss={() => onDismiss(selectedOption)}
39
+ onOk={() => onOk(selectedOption)}
40
+ >
41
+ <RadioButton.Group
42
+ value={selectedOption}
43
+ onValueChange={onChange}
44
+ >
45
+ {
46
+ options.map(
47
+ option => {
48
+ const optionKey = option?.key;
49
+ const colors = theme.colors;
50
+ return (
51
+ <RadioButton.Item
52
+ key={optionKey}
53
+ value={optionKey}
54
+ label={t(option.label)}
55
+ labelStyle={styles.optionLabel}
56
+ color={colors.checkboxChecked}
57
+ mode={'android'}
58
+ />
59
+ )
60
+ }
61
+ )
62
+ }
63
+ </RadioButton.Group>
64
+ </SettingsDialog>
65
+ );
66
+ }
@@ -0,0 +1,7 @@
1
+ export default function (theme) {
2
+ return {
3
+ optionLabel: {
4
+ fontSize: theme.fontSizes.m,
5
+ }
6
+ }
7
+ };