@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,12 @@
1
+
2
+ export default function(theme) {
3
+ return {
4
+ container: {
5
+ flex: 1,
6
+ backgroundColor: theme.colors.background,
7
+ },
8
+ title: {
9
+ fontSize: theme.fontSizes.m
10
+ }
11
+ }
12
+ };
@@ -0,0 +1,65 @@
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, useEffect, useRef } from "react";
16
+ import { useTranslation } from "react-i18next";
17
+ import { View, Text, StyleSheet, Animated } from "react-native";
18
+ import { useTheme } from "react-native-paper";
19
+
20
+ import { useConnectivityContext } from "@olea-bps/context-connectivity";
21
+
22
+ import componentStyles from "./styles";
23
+
24
+ function ConnectivityWarning({ children, bottomNavbarHeight }) {
25
+ const { isConnected } = useConnectivityContext();
26
+ const { t } = useTranslation();
27
+ const theme = useTheme();
28
+
29
+ const opacity = useRef(new Animated.Value(0)).current;
30
+
31
+ useEffect(() => {
32
+ opacity.setValue(0);
33
+ Animated.timing(opacity, {
34
+ toValue: 1,
35
+ duration: 1000,
36
+ useNativeDriver: true,
37
+ }).start();
38
+ }, [isConnected]);
39
+
40
+ const styles = useMemo(() => {
41
+ const baseStyles = componentStyles(theme);
42
+ return StyleSheet.create({
43
+ ...baseStyles,
44
+ warningContainer: {
45
+ ...baseStyles.warningContainer,
46
+ // -1 to avoid a small gap between the warning and the bottom navbar
47
+ marginBottom: bottomNavbarHeight - 1,
48
+ opacity: opacity,
49
+ },
50
+ });
51
+ }, [theme, bottomNavbarHeight, opacity]);
52
+
53
+ return (
54
+ <View style={styles.container}>
55
+ {children}
56
+ {!isConnected && (
57
+ <Animated.View style={[styles.warningContainer]}>
58
+ <Text style={styles.warningText}>{t("warning:noConnection")}</Text>
59
+ </Animated.View>
60
+ )}
61
+ </View>
62
+ );
63
+ }
64
+
65
+ export default ConnectivityWarning;
@@ -0,0 +1,19 @@
1
+ export default function (theme) {
2
+ return {
3
+ container: {
4
+ flex: 1,
5
+ },
6
+ warningContainer: {
7
+ position: "absolute",
8
+ bottom: 0,
9
+ width: "100%",
10
+ height: 30,
11
+ justifyContent: "center",
12
+ backgroundColor: theme.colors.error,
13
+ },
14
+ warningText: {
15
+ color: theme.colors.errorText,
16
+ textAlign: "center",
17
+ },
18
+ };
19
+ }
@@ -0,0 +1,232 @@
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,
20
+ Text,
21
+ View,
22
+ SafeAreaView,
23
+ Share,
24
+ Linking,
25
+ TouchableOpacity,
26
+ Platform,
27
+ ScrollView
28
+ } from 'react-native';
29
+ import {Appbar, Headline, List, withTheme} from "react-native-paper";
30
+
31
+ import { connect } from 'react-redux'
32
+ import {withTranslation} from "react-i18next";
33
+ import merge from 'lodash/merge';
34
+
35
+ import componentStyles from "./styles"
36
+ import { AppBar as AppbarComponent } from '@olea-bps/components';
37
+
38
+
39
+ /**
40
+ * Contact Detail Component
41
+ *
42
+ * Shows the detailed information of a contact with name and contact details.
43
+ * Provides a share functionality.
44
+ *
45
+ * Parameters:
46
+ * - contact: Contact object with all information about the contact
47
+ *
48
+ * Navigation-Parameters:
49
+ * - none
50
+ */
51
+ class ContactDetailComponent extends React.Component {
52
+ static propTypes = {
53
+ contact: PropTypes.object.isRequired
54
+ };
55
+
56
+ // Styles of this component
57
+ styles;
58
+
59
+ contact = null;
60
+
61
+
62
+ constructor(props) {
63
+ super(props);
64
+ // ------------------------------------------------------------------------
65
+ // PLUGIN FUNCTIONALITY
66
+ // ------------------------------------------------------------------------
67
+
68
+ const { pluginStyles,theme } = this.props;
69
+ this.styles = componentStyles(theme);
70
+
71
+ if(pluginStyles) {
72
+ this.styles = merge(this.styles, pluginStyles);
73
+ }
74
+
75
+ this.styles = StyleSheet.create(this.styles);
76
+
77
+ // ------------------------------------------------------------------------
78
+ };
79
+
80
+ /**
81
+ * Share function for contact
82
+ *
83
+ * @returns {Promise<void>}
84
+ * @private
85
+ */
86
+ async _onShare() {
87
+ try {
88
+ const { t } = this.props;
89
+
90
+ let phone = "";
91
+ if(this.contact.telephone.length > 0) {
92
+ phone += "\n"+ t('contact:phone') +": ";
93
+ this.contact.telephone.forEach((phoneNumber) => {
94
+ phone += phoneNumber.number + '\n';
95
+ });
96
+ }
97
+
98
+ let message = t('contact:title') + ' - ' + this.contact.firstName + ' ' + this.contact.lastName +
99
+ ((this.contact.building) ? "\n" + t('contact:building') + ": " + this.contact.building : '') +
100
+ ((this.contact.department) ? "\n" + t('contact:department') + ": " + this.contact.department : '') +
101
+ ((this.contact.room && this.contact.room.title) ? "\n" + t('contact:room') + ": " + this.contact.room.title : '') +
102
+ ((this.contact.email) ? "\n" + t('contact:email') + ": " + this.contact.email : '') +
103
+ phone;
104
+
105
+ const result = await Share.share({
106
+ message: message
107
+ });
108
+
109
+ if (result.action === Share.sharedAction) {
110
+ if (result.activityType) {
111
+ // shared with activity type of result.activityType
112
+ } else {
113
+ // shared
114
+ }
115
+ } else if (result.action === Share.dismissedAction) {
116
+ // dismissed
117
+ }
118
+ } catch (error) {
119
+ alert(error.message);
120
+ }
121
+ };
122
+
123
+ /**
124
+ * Render contact details content
125
+ *
126
+ * @returns {*}
127
+ * @private
128
+ */
129
+ _renderContent = () => {
130
+ const { contact, t } = this.props;
131
+ const { themeStyles } = this.props.theme;
132
+
133
+ let output = [];
134
+ let index = 1;
135
+
136
+
137
+
138
+
139
+ if(contact.building)
140
+ output.push(<List.Item key="building" title={t('contact:building')} description={contact.building}
141
+ descriptionStyle={themeStyles.textLighter} titleStyle={themeStyles.searchDetailTitle}
142
+ descriptionNumberOfLines={200}/>);
143
+
144
+ if(contact.department)
145
+ output.push(<List.Item key="department" title={t('contact:department')} description={contact.department}
146
+ descriptionStyle={themeStyles.textLighter} titleStyle={themeStyles.searchDetailTitle}
147
+ descriptionNumberOfLines={200}/>);
148
+
149
+ if(contact.room && contact.room.title)
150
+ output.push(<List.Item key="room" title={t('contact:room')} description={contact.room.title}
151
+ descriptionStyle={themeStyles.textLighter} titleStyle={themeStyles.searchDetailTitle}
152
+ descriptionNumberOfLines={200}/>);
153
+
154
+ if(contact.email)
155
+ output.push(<TouchableOpacity key="email" onPress={() => Linking.openURL('mailto:' + contact.email)}>
156
+ <List.Item title={t('contact:email')} description={contact.email}
157
+ descriptionStyle={themeStyles.textLighter} titleStyle={themeStyles.searchDetailTitle}
158
+ right={props => <List.Icon {...props} icon="email"/>}/>
159
+ </TouchableOpacity>
160
+ );
161
+
162
+ if(contact.telephone.length > 0) {
163
+ contact.telephone.forEach((phoneNumber) => {
164
+ output.push(
165
+ <TouchableOpacity key={'phone_'+ index} onPress={() => {
166
+ const formattedPhoneNumber = phoneNumber.number.replace(/\s/g, '');
167
+ Linking.openURL('tel:' + formattedPhoneNumber).catch(error => console.error(`ContactDetailComponent - Fehler beim öffnen des Telefons ${Platform.OS}`, error));
168
+ }}>
169
+ <List.Item
170
+ title={t('contact:phone') + ' ' + index}
171
+ description={phoneNumber.number}
172
+ descriptionStyle={themeStyles.textLighter}
173
+ titleStyle={themeStyles.searchDetailTitle}
174
+ right={props =>
175
+ <List.Icon {...props}
176
+ icon="phone"/>}
177
+ />
178
+ </TouchableOpacity>
179
+ );
180
+ index++;
181
+ });
182
+ }
183
+
184
+
185
+ return (
186
+ <ScrollView style={this.styles.containerInner}>
187
+ <Headline style={this.styles.name}>{contact.firstName} {contact.lastName}</Headline>
188
+ {output}
189
+ <View style={this.styles.space}/>
190
+ </ScrollView>
191
+ );
192
+ };
193
+
194
+ render() {
195
+ // ------------------------------------------------------------------------
196
+ // PLUGIN FUNCTIONALITY
197
+ // ------------------------------------------------------------------------
198
+ const PluginComponent = this.props.pluginComponent;
199
+ if (PluginComponent) {
200
+ return <PluginComponent />;
201
+ }
202
+ // ------------------------------------------------------------------------
203
+
204
+ const {themeStyles} = this.props.theme;
205
+ const { contact, t } = this.props;
206
+
207
+ if(!contact){
208
+ return (<Text>{t('contact:couldNotLoad')}</Text>);
209
+ }
210
+
211
+ this.contact = contact;
212
+
213
+ return (
214
+ <SafeAreaView style={[this.styles.container, themeStyles.safeAreaContainer]}>
215
+ <AppbarComponent {...this.props}
216
+ title={t('contact:contactInformation')}
217
+ rightAction={<Appbar.Action icon="share-variant" onPress={this._onShare.bind(this)}/>}/>
218
+ {this._renderContent()}
219
+ </SafeAreaView>
220
+ );
221
+ }
222
+ }
223
+
224
+
225
+ const mapStateToProps = state => {
226
+ return {
227
+ pluginComponent: state.pluginReducer.contactDetail.component,
228
+ pluginStyles: state.pluginReducer.contactDetail.styles
229
+ };
230
+ };
231
+
232
+ export default connect(mapStateToProps, null)(withTranslation()(withTheme(ContactDetailComponent)))
@@ -0,0 +1,32 @@
1
+ export default function(theme) {
2
+ return {
3
+ container: {
4
+ flex: 1,
5
+ },
6
+ containerInner: {
7
+ flex: 1,
8
+ paddingHorizontal: theme.paddings.default,
9
+ paddingVertical: theme.paddings.default
10
+ },
11
+ activity: {
12
+ marginTop: theme.paddings.default
13
+ },
14
+ badges: {
15
+ flexDirection: 'row',
16
+ flexWrap: 'wrap',
17
+ paddingHorizontal: theme.paddings.small
18
+ },
19
+ badge: {
20
+ marginRight: theme.paddings.xsmall,
21
+ marginBottom: theme.paddings.xsmall
22
+ },
23
+ name: {
24
+ paddingLeft: theme.paddings.xsmall + theme.paddings.small,
25
+ fontSize: theme.fontSizes.title,
26
+ lineHeight: theme.lineHeights.contactName
27
+ },
28
+ space: {
29
+ height: theme.paddings.large
30
+ }
31
+ };
32
+ }