@olea-bps/base 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 (268) hide show
  1. package/components/AppBar/index.js +84 -0
  2. package/components/AppBar/styles.js +27 -0
  3. package/components/BookDetail/index.js +268 -0
  4. package/components/BookDetail/styles.js +124 -0
  5. package/components/ComponentJobsFilter/index.js +188 -0
  6. package/components/ComponentJobsFilter/styles.js +12 -0
  7. package/components/ConnectivityWarning/index.js +65 -0
  8. package/components/ConnectivityWarning/styles.js +19 -0
  9. package/components/ContactDetail/index.js +232 -0
  10. package/components/ContactDetail/styles.js +32 -0
  11. package/components/CourseDetail/index.js +357 -0
  12. package/components/CourseDetail/styles.js +59 -0
  13. package/components/CourseDetailDialog/index.js +169 -0
  14. package/components/CourseDetailDialog/styles.js +116 -0
  15. package/components/CourseInfo/index.js +219 -0
  16. package/components/CourseInfo/styles.js +40 -0
  17. package/components/DevelopmentDialog/index.js +214 -0
  18. package/components/DevelopmentDialog/styles.js +10 -0
  19. package/components/EventCodeInput/index.js +149 -0
  20. package/components/EventCodeInput/styles.js +108 -0
  21. package/components/FlexMenuEntry/index.js +84 -0
  22. package/components/FlexMenuEntry/styles.js +27 -0
  23. package/components/MainMenuEntry/index.js +88 -0
  24. package/components/MainMenuEntry/styles.js +28 -0
  25. package/components/MealItem/index.js +87 -0
  26. package/components/MealItem/styles.js +84 -0
  27. package/components/MensaMenu/index.js +305 -0
  28. package/components/MensaMenu/styles.js +94 -0
  29. package/components/MensaSlider/index.js +188 -0
  30. package/components/MensaSlider/styles.js +53 -0
  31. package/components/Modal/index.js +106 -0
  32. package/components/Modal/styles.js +8 -0
  33. package/components/NewsDetail/index.js +377 -0
  34. package/components/NewsDetail/styles.js +77 -0
  35. package/components/NewsList/index.js +120 -0
  36. package/components/NewsList/styles.js +19 -0
  37. package/components/NewsListItem/index.js +89 -0
  38. package/components/NewsListItem/styles.js +32 -0
  39. package/components/OtherCourses/index.js +152 -0
  40. package/components/OtherCourses/styles.js +10 -0
  41. package/components/PtsDeparture/index.js +140 -0
  42. package/components/PtsDeparture/styles.js +7 -0
  43. package/components/PtsStation/index.js +186 -0
  44. package/components/PtsStation/styles.js +47 -0
  45. package/components/QuickLinks/index.js +127 -0
  46. package/components/QuickLinks/styles.js +45 -0
  47. package/components/RoomDetail/index.js +281 -0
  48. package/components/RoomDetail/styles.js +56 -0
  49. package/components/ScaledImage/index.js +92 -0
  50. package/components/SearchResults/index.js +362 -0
  51. package/components/SearchResults/styles.js +59 -0
  52. package/components/SettingSection/index.js +54 -0
  53. package/components/SettingSection/styles.js +15 -0
  54. package/components/SettingsDialog/index.js +52 -0
  55. package/components/SettingsDialog/styles.js +12 -0
  56. package/components/SettingsDialogRadio/index.js +66 -0
  57. package/components/SettingsDialogRadio/styles.js +7 -0
  58. package/components/SettingsDialogSelect/index.js +73 -0
  59. package/components/SettingsDialogSelect/styles.js +7 -0
  60. package/components/TimetableCodeInput/index.js +205 -0
  61. package/components/TimetableCodeInput/styles.js +28 -0
  62. package/components/TimetableDay/index.js +252 -0
  63. package/components/TimetableDay/styles.js +103 -0
  64. package/components/TimetableEvent/index.js +163 -0
  65. package/components/TimetableEvent/styles.js +108 -0
  66. package/components/TimetableList/index.js +180 -0
  67. package/components/TimetableList/styles.js +106 -0
  68. package/components/TimetableMonth/index.js +156 -0
  69. package/components/TimetableMonth/styles.js +29 -0
  70. package/components/TimetableWeek/index.js +230 -0
  71. package/components/TimetableWeek/styles.js +58 -0
  72. package/components/TopNews/index.js +282 -0
  73. package/components/TopNews/styles.js +125 -0
  74. package/components/TopNewsHtwk/index.js +279 -0
  75. package/components/TopNewsHtwk/styles.js +142 -0
  76. package/components/WebView/index.js +108 -0
  77. package/components/WebView/styles.js +11 -0
  78. package/context/context-callmanager/TucCallManager.js +74 -0
  79. package/context/context-callmanager/index.js +128 -0
  80. package/context/context-canteen/AsistServerApiProvider.js +126 -0
  81. package/context/context-canteen/CollektorVersion2ApiProvider.js +100 -0
  82. package/context/context-canteen/index.js +692 -0
  83. package/context/context-connectivity/index.js +85 -0
  84. package/context/context-event/AsistServerClient.js +82 -0
  85. package/context/context-event/index.js +205 -0
  86. package/context/context-flex-menu/AsistServerApiProvider.js +0 -0
  87. package/context/context-flex-menu/CollectorVersion2ApiProvider.js +32 -0
  88. package/context/context-flex-menu/index.js +160 -0
  89. package/context/context-info-dialog/CollektorVersion2ApiProvider.js +53 -0
  90. package/context/context-info-dialog/ProviderErrors.js +22 -0
  91. package/context/context-info-dialog/index.js +190 -0
  92. package/context/context-mails/MailService.js +147 -0
  93. package/context/context-mails/TucUnseenApiProvider.js +65 -0
  94. package/context/context-mails/index.js +131 -0
  95. package/context/context-news/CollektorVersion2ApiProvider.js +68 -0
  96. package/context/context-news/index.js +155 -0
  97. package/context/context-public-transport-ticket/CollektorVersion2ApiProvider.js +45 -0
  98. package/context/context-public-transport-ticket/ProviderErrors.js +11 -0
  99. package/context/context-public-transport-ticket/index.js +175 -0
  100. package/context/context-timetable/CollectorVersion2ApiProvider.js +102 -0
  101. package/context/context-timetable/ProviderErrors.js +22 -0
  102. package/context/context-timetable/TimetableService.js +357 -0
  103. package/context/context-timetable/index.js +215 -0
  104. package/context/context-user/index.js +586 -0
  105. package/index.js +178 -0
  106. package/libraries/base-api-provider/hooks.js +24 -0
  107. package/libraries/base-api-provider/http-api-provider.js +168 -0
  108. package/libraries/base-api-provider/index.js +20 -0
  109. package/libraries/core/api/canteens.js +88 -0
  110. package/libraries/core/api/corona.js +45 -0
  111. package/libraries/core/api/courses.js +54 -0
  112. package/libraries/core/api/device.js +98 -0
  113. package/libraries/core/api/feed.js +144 -0
  114. package/libraries/core/api/feedback.js +123 -0
  115. package/libraries/core/api/jobs.js +48 -0
  116. package/libraries/core/api/library.js +67 -0
  117. package/libraries/core/api/lostfound.js +77 -0
  118. package/libraries/core/api/occupancy.js +44 -0
  119. package/libraries/core/api/officehours.js +25 -0
  120. package/libraries/core/api/poi.js +25 -0
  121. package/libraries/core/api/pts.js +68 -0
  122. package/libraries/core/api/rooms.js +31 -0
  123. package/libraries/core/api/survey.js +121 -0
  124. package/libraries/core/api/telephone.js +32 -0
  125. package/libraries/core/api/tucrooms.js +31 -0
  126. package/libraries/core/constants/actions.js +75 -0
  127. package/libraries/core/constants/api.js +146 -0
  128. package/libraries/core/constants/enums.js +5 -0
  129. package/libraries/core/helper/date.js +9 -0
  130. package/libraries/core/helper/format.helper.js +2 -0
  131. package/libraries/core/index.js +60 -0
  132. package/libraries/core/redux/actions/notifications.js +6 -0
  133. package/libraries/core/redux/actions/setting.js +75 -0
  134. package/libraries/core/redux/actions/state.js +74 -0
  135. package/libraries/core/redux/asyncDispatch.js +27 -0
  136. package/libraries/core/redux/reducers/api.js +190 -0
  137. package/libraries/core/redux/reducers/index.js +32 -0
  138. package/libraries/core/redux/reducers/notifications.js +16 -0
  139. package/libraries/core/redux/reducers/setting.js +99 -0
  140. package/libraries/core/redux/reducers/state.js +122 -0
  141. package/libraries/core/redux/selectors.js +123 -0
  142. package/libraries/core/redux/store.js +40 -0
  143. package/libraries/core/services/data.js +96 -0
  144. package/libraries/core/services/root-navigation.js +36 -0
  145. package/libraries/core/services/search.js +175 -0
  146. package/libraries/core-plugins/enums/replaceTypes.js +53 -0
  147. package/libraries/core-plugins/index.js +21 -0
  148. package/libraries/core-plugins/redux/actions/plugin.js +13 -0
  149. package/libraries/core-plugins/redux/reducers/plugin.js +210 -0
  150. package/libraries/icons-openasist/index.js +143 -0
  151. package/libraries/notifications/index.js +268 -0
  152. package/libraries/notifications/services/subscriber.service.js +123 -0
  153. package/libraries/react-native-webview-autoheight/README.md +47 -0
  154. package/libraries/react-native-webview-autoheight/index.js +140 -0
  155. package/libraries/react-native-webview-autoheight/package.json +37 -0
  156. package/libraries/react-native-webview-autoheight/utils.js +268 -0
  157. package/libraries/redux-offline/.eslintignore +1 -0
  158. package/libraries/redux-offline/.github/ISSUE_TEMPLATE/redux-offline-core-issues-template.md +25 -0
  159. package/libraries/redux-offline/.prettierrc +6 -0
  160. package/libraries/redux-offline/LICENSE +21 -0
  161. package/libraries/redux-offline/README.md +133 -0
  162. package/libraries/redux-offline/flow-typed/npm/redux-logger_vx.x.x.js +109 -0
  163. package/libraries/redux-offline/flow-typed/npm/redux_v4.x.x.js +100 -0
  164. package/libraries/redux-offline/lib/actions.js +46 -0
  165. package/libraries/redux-offline/lib/config.js +15 -0
  166. package/libraries/redux-offline/lib/constants.js +17 -0
  167. package/libraries/redux-offline/lib/defaults/defaultCommit.js +11 -0
  168. package/libraries/redux-offline/lib/defaults/defaultRollback.js +11 -0
  169. package/libraries/redux-offline/lib/defaults/detectNetwork.js +33 -0
  170. package/libraries/redux-offline/lib/defaults/detectNetwork.native.js +211 -0
  171. package/libraries/redux-offline/lib/defaults/discard.js +18 -0
  172. package/libraries/redux-offline/lib/defaults/effect.js +87 -0
  173. package/libraries/redux-offline/lib/defaults/index.js +32 -0
  174. package/libraries/redux-offline/lib/defaults/offlineStateLens.js +24 -0
  175. package/libraries/redux-offline/lib/defaults/persist.js +9 -0
  176. package/libraries/redux-offline/lib/defaults/persist.native.js +17 -0
  177. package/libraries/redux-offline/lib/defaults/persistAutoRehydrate.js +8 -0
  178. package/libraries/redux-offline/lib/defaults/queue.js +27 -0
  179. package/libraries/redux-offline/lib/defaults/retry.js +29 -0
  180. package/libraries/redux-offline/lib/index.js +115 -0
  181. package/libraries/redux-offline/lib/middleware.js +56 -0
  182. package/libraries/redux-offline/lib/offlineActionTracker.js +43 -0
  183. package/libraries/redux-offline/lib/send.js +112 -0
  184. package/libraries/redux-offline/lib/types.js +3 -0
  185. package/libraries/redux-offline/lib/updater.js +111 -0
  186. package/libraries/redux-offline/package.json +69 -0
  187. package/libraries/redux-offline/src/__tests__/defaults/discard.js +22 -0
  188. package/libraries/redux-offline/src/__tests__/defaults/effect.js +118 -0
  189. package/libraries/redux-offline/src/__tests__/index.js +116 -0
  190. package/libraries/redux-offline/src/__tests__/middleware.js +185 -0
  191. package/libraries/redux-offline/src/__tests__/offlineActionTracker.js +54 -0
  192. package/libraries/redux-offline/src/__tests__/send.js +208 -0
  193. package/libraries/redux-offline/src/actions.js +36 -0
  194. package/libraries/redux-offline/src/config.js +9 -0
  195. package/libraries/redux-offline/src/constants.js +18 -0
  196. package/libraries/redux-offline/src/defaults/defaultCommit.js +7 -0
  197. package/libraries/redux-offline/src/defaults/defaultRollback.js +7 -0
  198. package/libraries/redux-offline/src/defaults/detectNetwork.js +16 -0
  199. package/libraries/redux-offline/src/defaults/detectNetwork.native.js +148 -0
  200. package/libraries/redux-offline/src/defaults/discard.js +19 -0
  201. package/libraries/redux-offline/src/defaults/effect.js +86 -0
  202. package/libraries/redux-offline/src/defaults/index.js +25 -0
  203. package/libraries/redux-offline/src/defaults/offlineStateLens.js +11 -0
  204. package/libraries/redux-offline/src/defaults/persist.js +4 -0
  205. package/libraries/redux-offline/src/defaults/persist.native.js +9 -0
  206. package/libraries/redux-offline/src/defaults/persistAutoRehydrate.js +4 -0
  207. package/libraries/redux-offline/src/defaults/queue.js +20 -0
  208. package/libraries/redux-offline/src/defaults/retry.js +18 -0
  209. package/libraries/redux-offline/src/index.js +138 -0
  210. package/libraries/redux-offline/src/middleware.js +52 -0
  211. package/libraries/redux-offline/src/offlineActionTracker.js +40 -0
  212. package/libraries/redux-offline/src/send.js +111 -0
  213. package/libraries/redux-offline/src/types.js +127 -0
  214. package/libraries/redux-offline/src/updater.js +141 -0
  215. package/libraries/redux-offline/typings.d.ts +150 -0
  216. package/libraries/redux-offline/yarn.lock +6460 -0
  217. package/libraries/stored-state/index.js +155 -0
  218. package/package.json +68 -0
  219. package/views/Callmanager/index.js +148 -0
  220. package/views/Callmanager/styles.js +62 -0
  221. package/views/Canteens/index.js +383 -0
  222. package/views/Canteens/styles.js +89 -0
  223. package/views/Dashboard/index.js +176 -0
  224. package/views/Dashboard/styles.js +16 -0
  225. package/views/DashboardHtwk/index.js +197 -0
  226. package/views/DashboardHtwk/styles.js +24 -0
  227. package/views/Event/index.js +373 -0
  228. package/views/Event/styles.js +63 -0
  229. package/views/FeedList/index.js +165 -0
  230. package/views/FeedList/styles.js +15 -0
  231. package/views/FeedNews/index.js +243 -0
  232. package/views/FeedNews/styles.js +32 -0
  233. package/views/Flexmenu/index.js +185 -0
  234. package/views/Flexmenu/styles.js +62 -0
  235. package/views/FlexmenuWebview/index.js +167 -0
  236. package/views/FlexmenuWebview/styles.js +16 -0
  237. package/views/Howhy/index.js +151 -0
  238. package/views/Howhy/styles.js +11 -0
  239. package/views/Jobs/index.js +217 -0
  240. package/views/Jobs/styles.js +41 -0
  241. package/views/MainMenu/index.js +283 -0
  242. package/views/MainMenu/styles.js +36 -0
  243. package/views/NewsTabbar/index.js +164 -0
  244. package/views/NewsTabbar/styles.js +27 -0
  245. package/views/Opal/index.js +136 -0
  246. package/views/Opal/styles.js +11 -0
  247. package/views/PublicTransportTicket/index.js +173 -0
  248. package/views/PublicTransportTicket/styles.js +17 -0
  249. package/views/Search/index.js +186 -0
  250. package/views/Search/styles.js +67 -0
  251. package/views/SettingsAccessibility/index.js +148 -0
  252. package/views/SettingsAccessibility/styles.js +13 -0
  253. package/views/SettingsAppInfo/index.js +86 -0
  254. package/views/SettingsAppInfo/styles.js +18 -0
  255. package/views/SettingsCanteens/index.js +249 -0
  256. package/views/SettingsCanteens/styles.js +33 -0
  257. package/views/SettingsGeneral/index.js +173 -0
  258. package/views/SettingsGeneral/styles.js +28 -0
  259. package/views/SettingsNotifications/index.js +204 -0
  260. package/views/SettingsNotifications/styles.js +38 -0
  261. package/views/SettingsUser/index.js +170 -0
  262. package/views/SettingsUser/styles.js +17 -0
  263. package/views/TimetableCalendar/index.js +387 -0
  264. package/views/TimetableCalendar/styles.js +121 -0
  265. package/views/TimetableList/index.js +402 -0
  266. package/views/TimetableList/styles.js +55 -0
  267. package/views/Webviews/index.js +158 -0
  268. package/views/Webviews/styles.js +11 -0
@@ -0,0 +1,85 @@
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, { createContext, useState, useEffect, useContext } from "react";
16
+ import NetInfo from "@react-native-community/netinfo";
17
+
18
+ export const ConnectivityContext = createContext();
19
+
20
+ export function ConnectivityContextProvider({ children }) {
21
+ let [networkState, setNetworkState] = useState({
22
+ isConnected: true,
23
+ isInternetReachable: true,
24
+ });
25
+
26
+ useEffect(() => {
27
+ const fetchInitialState = async () => {
28
+ const state = await NetInfo.fetch();
29
+ setNetworkState({
30
+ isConnected: state.isConnected,
31
+ isInternetReachable: state.isInternetReachable,
32
+ });
33
+ };
34
+
35
+ fetchInitialState();
36
+
37
+ const unsubscribe = NetInfo.addEventListener((state) => {
38
+ setNetworkState({
39
+ isConnected: state.isConnected,
40
+ isInternetReachable: state.isInternetReachable,
41
+ });
42
+ });
43
+
44
+ return () => unsubscribe();
45
+ }, []);
46
+
47
+ return (
48
+ <ConnectivityContext.Provider value={networkState}>
49
+ {children}
50
+ </ConnectivityContext.Provider>
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Hook, der den Connectivity-Kontext verwendet.
56
+ * @returns {ConnectivityContext} Der Connectivity-Kontext.
57
+ * @returns {boolean} Der Connectivity-Kontext.isConnected.
58
+ * @returns {boolean} Der Connectivity-Kontext.isInternetReachable.
59
+ * @example
60
+ * import { useConnectivityContext } from '@olea-bps/context-connectivity';
61
+ *
62
+ * function MyComponent() {
63
+ * const { isConnected, isInternetReachable } = useConnectivityContext();
64
+ * }
65
+ */
66
+ export function useConnectivityContext() {
67
+ return useContext(ConnectivityContext);
68
+ }
69
+
70
+ /**
71
+ * Hook, der die Netzwerkstatuswerte in einem Array bereitstellt.
72
+ * @returns {Array} Ein Array mit den Netzwerkstatuswerten.
73
+ * @returns {boolean} return[0] - Gibt an, ob das Gerät mit dem Netzwerk verbunden ist.
74
+ * @returns {boolean} return[1] - Gibt an, ob das Internet erreichbar ist.
75
+ * @example
76
+ * import { useNetInfo } from '@olea-bps/context-connectivity';
77
+ *
78
+ * function MyComponent() {
79
+ * const [isConnected, isInternetReachable] = useNetInfo();
80
+ * }
81
+ */
82
+ export function useNetInfo() {
83
+ const { isConnected, isInternetReachable } = useContext(ConnectivityContext);
84
+ return [isConnected, isInternetReachable];
85
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Client to get Events from ASiST server
3
+ */
4
+ export default class AsistServerClient {
5
+ /**
6
+ * Base URL which is expanded to generate the request URLs.
7
+ * @private
8
+ */
9
+ #baseUrl
10
+
11
+ /**
12
+ * University code which is communicated to the ASiST server via the request URL in order to retrieve the events of the correct university.
13
+ * @private
14
+ */
15
+ #university
16
+
17
+ /**
18
+ * Returns the request URL to get all events from the ASiST server.
19
+ * @returns {URL}
20
+ */
21
+ // If available implement as private get property
22
+ getAllUrl() {
23
+ return new URL(`${this.#baseUrl}/${this.#university}/events`);
24
+ }
25
+
26
+ /**
27
+ * Construct a ASiST server rest api client.
28
+ * @param {String} baseUrl URL which is used as the basis for the query URLs.
29
+ * @param {String} university University code of the university to be queried.
30
+ */
31
+ constructor(baseUrl, university) {
32
+ this.#baseUrl = baseUrl;
33
+ this.#university = university;
34
+ }
35
+
36
+ /**
37
+ * Returns a list of all events from the queried university.
38
+ * @returns {Array} Array of all event objects
39
+ */
40
+ getAll() {
41
+ const getAllEventsURL = this.getAllUrl();
42
+
43
+ console.debug(`Get all events: ${getAllEventsURL}`)
44
+
45
+ return fetch(
46
+ getAllEventsURL,
47
+ {
48
+ 'headers': AsistServerClient.generateHeaders(),
49
+ }
50
+ ).then(allEventResponse => allEventResponse.json())
51
+ }
52
+
53
+ /**
54
+ * Return list of events for the personal code.
55
+ * @param {String} personalCode Personal code for market events
56
+ * @returns {Array}
57
+ */
58
+ getByPersonalCode(personalCode) {
59
+ // If available implement query parameter with 'searchParams.set': personalEventsURL.searchParams.set('code', personalCode);
60
+ const personalEventsURL = `${this.getAllUrl()}?code=${personalCode}`;
61
+
62
+ console.debug(`Get personal events: ${personalEventsURL}`)
63
+
64
+ return fetch(
65
+ personalEventsURL,
66
+ {
67
+ 'headers': AsistServerClient.generateHeaders(),
68
+ }
69
+ ).then(personalEventResponse => personalEventResponse.json())
70
+ }
71
+
72
+ /**
73
+ * Returns standart headers für asist server requests.
74
+ * @returns {object}
75
+ */
76
+ // If available implement as private
77
+ static generateHeaders() {
78
+ return {
79
+ 'Accept': 'application/json',
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,205 @@
1
+ import {
2
+ useContext,
3
+ createContext,
4
+ useMemo,
5
+ useCallback,
6
+ useEffect
7
+ } from 'react';
8
+
9
+ import { useTheme } from 'react-native-paper';
10
+
11
+ import { DateTime } from 'luxon';
12
+
13
+ import { useSecureStoredState } from '../../libraries/stored-state';
14
+
15
+ import AsistServerClient from './AsistServerClient';
16
+
17
+ const EventCodeStoreKey = 'event.eventCode';
18
+ const EventsStoreKey = 'event.events';
19
+ const PersonalEventsStoreKey = 'event.personelEvents';
20
+
21
+ /**
22
+ * Context for event api
23
+ */
24
+ export const EventContext = createContext(null);
25
+
26
+ /**
27
+ * Extendet context provider for EventAPIContext.
28
+ * Use settings in Settings.js to generate context values and event api client.
29
+ * currently only supports event api client for asist server rest api.
30
+ * But can be extendet to support more event services.
31
+ * @param {props} properties of provider
32
+ */
33
+ export default function EventContextProvider({ children }) {
34
+ const { appSettings } = useTheme();
35
+ const eventAPIProvider = appSettings?.modules?.event?.api?.provider;
36
+ const eventAPIBaseUrl = appSettings?.modules?.event?.api?.baseUrl;
37
+ const university = appSettings?.api?.university ?? null;
38
+
39
+ const [events, setEvents] = useSecureStoredState(EventsStoreKey);
40
+ const [personalEventsCode, setPersonalEventsCode, deletePersonalEventsCode] = useSecureStoredState(EventCodeStoreKey, null, true);
41
+ const [personalEvents, setPersonalEvents, deletePersonalEvents] = useSecureStoredState(PersonalEventsStoreKey,)
42
+
43
+ const sortedEvents = useMemo(
44
+ () => {
45
+ // Sortiren der Events wenn welche vorhanden sind
46
+ if (Array.isArray(events)) {
47
+ // Kopieren der vorhanden Events, damit neues Array entsteht und reactivität gewahrt wird
48
+ const sortingEvents = [...events];
49
+
50
+ // Die Events werden zuerst nach der Endzeit sortiert und danach nach der Startzeit
51
+ // Somit werden dem Nutzer die Events nach Startzeit angezeigt
52
+ // Haben Events die selbe Startzeit, werden diese sortiert nach Endzeit dargstellt
53
+ sortingEvents
54
+ // Soriterung nach Endzeit
55
+ .sort((first, second) => DateTime.fromISO(first.end) - DateTime.fromISO(second.end))
56
+ // Sortierung nach Startzeit
57
+ .sort((first, second) => DateTime.fromISO(first.begin) - DateTime.fromISO(second.begin));
58
+
59
+ return sortingEvents;
60
+ } else {
61
+ return null;
62
+ }
63
+ },
64
+ [events]
65
+ )
66
+
67
+ const eventAPIClient = useMemo(
68
+
69
+ () => {
70
+ switch (eventAPIProvider?.toLowerCase()) {
71
+ case 'asist-server':
72
+ return new AsistServerClient(eventAPIBaseUrl, university);
73
+ default:
74
+ return null;
75
+ }
76
+ },
77
+ [eventAPIProvider, eventAPIBaseUrl, university]
78
+ )
79
+
80
+ const refreshEvents = useCallback(
81
+ () => eventAPIClient.getAll()
82
+ .then(setEvents),
83
+ [eventAPIClient]
84
+ )
85
+
86
+ const refreshPersonalEvents = useCallback(
87
+ () => eventAPIClient.getByPersonalCode(personalEventsCode)
88
+ .then(setPersonalEvents),
89
+ [eventAPIClient, personalEventsCode]
90
+ )
91
+
92
+ function deletePersonalEventsCodeAndPersonalEvents() {
93
+ deletePersonalEventsCode();
94
+ deletePersonalEvents();
95
+ }
96
+
97
+ useEffect(
98
+ () => {
99
+ refreshEvents();
100
+ },
101
+ [refreshEvents]
102
+ )
103
+
104
+ useEffect(
105
+ () => {
106
+ if (personalEventsCode) {
107
+ refreshPersonalEvents();
108
+ }
109
+ },
110
+ [eventAPIClient, personalEventsCode, refreshPersonalEvents]
111
+ )
112
+
113
+ return (
114
+ <EventContext.Provider
115
+ value={
116
+ {
117
+ events: sortedEvents,
118
+ refreshEvents: refreshEvents,
119
+
120
+ personalEvents: personalEvents,
121
+ refreshPersonalEvents: refreshPersonalEvents,
122
+
123
+ personalEventsCode: personalEventsCode,
124
+ setPersonalEventsCode: setPersonalEventsCode,
125
+ deletePersonalEventsCode: deletePersonalEventsCodeAndPersonalEvents,
126
+
127
+ apiClient: eventAPIClient,
128
+ }
129
+ }
130
+ >
131
+ {children}
132
+ </EventContext.Provider>
133
+ )
134
+ }
135
+
136
+ /**
137
+ * Dieser Hook stellt den EventContext bereit.
138
+ *
139
+ * Dieser Hook sollte grundsätlich nur von anderen Hooks verwendet werden.
140
+ * @returns {object} Eventkontext
141
+ */
142
+ export function useEventContext() {
143
+ const context = useContext(EventContext);
144
+ if (context === null) {
145
+ throw new Error('useEventContext must be used within an EventContextProvider');
146
+ }
147
+ return context;
148
+ }
149
+
150
+ /**
151
+ * Über diesen Hook gelangt man an die persönlichen Veranstaltungen.
152
+ * Dafür wird der persönliche Veranstaltungscode (siehe {@link usePersonalEventsCode }) verwendet.
153
+ *
154
+ * @returns {[Array, () => Promise]} Liste der persönlichen Veranstalltungen entsprechnd des persönlichen Codes
155
+ * @example
156
+ * const [personalEvents, refreshPersonalEvents] = usePersonalEvents();
157
+ */
158
+ export function usePersonalEvents() {
159
+ const eventContext = useEventContext();
160
+
161
+ return [eventContext.personalEvents, eventContext.refreshPersonalEvents];
162
+ }
163
+
164
+ /**
165
+ *
166
+ * @returns {[Array, () => void]}
167
+ * @example
168
+ * const [events, refreshEvents] = useEvents();
169
+ *
170
+ * useEffect(
171
+ * () => {
172
+ * refreshEvents();
173
+ * },
174
+ * []
175
+ * );
176
+ *
177
+ * return (
178
+ * events.map(
179
+ * event => JSON.stringify(event);
180
+ * )
181
+ * )
182
+ */
183
+ export function useEvents() {
184
+ const eventContext = useEventContext();
185
+ return [eventContext.events, eventContext.refreshEvents];
186
+ }
187
+
188
+ /**
189
+ * Hook to get and set personal code.
190
+ * Please use hook like: const [personalCode, setPersonalCode] = usePersonalCode();
191
+ * currently not in use.
192
+ * @returns {[string, () => void, () => void]} First element is the value of the personal code and the second element a update function for the personal code.
193
+ */
194
+ export function usePersonalEventsCode() {
195
+ const eventContext = useEventContext();
196
+ return [eventContext.personalEventsCode, eventContext.setPersonalEventsCode, eventContext.deletePersonalEventsCode];
197
+ }
198
+
199
+ /**
200
+ * Hook to get event api client from context.
201
+ * @returns {Object}
202
+ */
203
+ export function useEventApiClient() {
204
+ return useEventContext().apiClient;
205
+ }
@@ -0,0 +1,32 @@
1
+ import HttpApiProvider, { JsonContentType } from '../../libraries/base-api-provider'
2
+
3
+ export default class CollectorVersion2ApiProvider extends HttpApiProvider {
4
+
5
+ constructor(baseUrl, acceptingLanguages) {
6
+ // ContentTypes wird auf JSON festgesetzt, da die Kollektoren nur JSON sprechen.
7
+ super(baseUrl, acceptingLanguages, [JsonContentType]);
8
+ }
9
+
10
+ getMenuEntriesUrl() {
11
+ return this.extendBaseUrl(['app-menu-entries']);
12
+ }
13
+
14
+ getMenuEntries() {
15
+ const getUrl = this.getMenuEntriesUrl();
16
+
17
+ return this.get(getUrl)
18
+ .then(response => response.json());
19
+ }
20
+
21
+ /**
22
+ * Creates a CollektorVersion2ApiProvider instance initialised to a list of standard languages, where the mainLanguage parameter specifies the mainLanguage.
23
+ * @param {string} baseUrl URL which is used as the basis for the query URLs.
24
+ * @param {string} mainLanguage Main language which is prioritised.
25
+ * @returns {CollektorVersion2ApiProvider} Created CollectorVersion2ApiProvider instance.
26
+ */
27
+ static from(baseUrl, mainLanguage = 'de') {
28
+ const acceptingLanguages = CollectorVersion2ApiProvider.languagesFromMainLanguages(mainLanguage);
29
+
30
+ return new CollectorVersion2ApiProvider(baseUrl, acceptingLanguages);
31
+ }
32
+ }
@@ -0,0 +1,160 @@
1
+ import { createContext, useState, useEffect, useContext, useMemo, useCallback } from 'react'
2
+
3
+ import { useTheme } from 'react-native-paper';
4
+ import AsyncStorage from '@react-native-async-storage/async-storage';
5
+
6
+ import { useStagingServer } from '../../libraries/core';
7
+
8
+ import CollectorVersion2ApiProvider from './CollectorVersion2ApiProvider'
9
+
10
+ const AsistServerProviderName = 'asist-server';
11
+ const CollectorVersion2ProviderName = 'hs-collector-v2';
12
+
13
+ const MenuEntriesStoreKey = 'flexMenu.menuEnries';
14
+
15
+ /**
16
+ * @typedef {Object} MenuEntry
17
+ * @property {string} id Id des Menüeintrages
18
+ * @property {string[]} subMenuEntries Liste der IDs der Untermenüeinträge
19
+ * @property {string} parentMenuEntry ID des Elternmenüeintrages
20
+ * @property {string} openIn `webbrowser` wenn die URL im Browser geöffent werden soll. `webview` wenn die URL in einer Webview geöffent werden soll.
21
+ * @property {string} type - Falls dieser Menüeintrag ein Hauptmenüeintrag ist, ist hier der zugeötige Tab anzugeben
22
+ * @property {string} language Sprache des Menüeintrages. Die möglichen Werte sind in der Settings.js in der Sprachenliste als `extCode` zu finden
23
+ * @property {string} title Titel des Menüeintrages
24
+ * @property {string} description Beschreibung
25
+ * @property {string} url URL des Menüeintrages. Wie diese URL geöffnet wird, wird über {@link openIn } geregelt
26
+ * @property {string} icon Name des anzuzeigenen Icons
27
+ * @property {string} image URL des Anzuziegenden Bildes
28
+ */
29
+
30
+ export const FlexMenuContext = createContext({
31
+ menuEntries: [],
32
+ });
33
+
34
+ function FlexMenuContextProvider({ children }) {
35
+ const componentName = FlexMenuContextProvider.name;
36
+ const theme = useTheme();
37
+ const isStagingServerActive = useStagingServer();
38
+
39
+ // Einstellungen für das InfoDialog-Moduls
40
+ const flexMenuSettings = theme?.appSettings?.modules?.flexmenu;
41
+ // Einstellungen für die API-Provider
42
+ const flexMenuApiSettings = flexMenuSettings?.api;
43
+ // Soll der Staging-Provider verwendet werden?
44
+ const flexMenuApiProviderSettings = isStagingServerActive
45
+ // Wenn ja, werden die Staging Provider-Einstellungen geladen
46
+ ? flexMenuApiSettings?.staging
47
+ // Wenn nein, werden die productiven Provider-Einstellungen geladen
48
+ : flexMenuApiSettings?.production;
49
+ // Basis URL der API
50
+ const flexMenuApiBaseUrl = flexMenuApiProviderSettings?.url;
51
+ // API-Provider
52
+ const flexMenuApiProvider = flexMenuApiProviderSettings?.provider;
53
+
54
+ const [menuEntries, setMenuEntries] = useState(null);
55
+
56
+ // Estellen des API-Providers bzw. erneuern wenn sich Einstellungen ändern.
57
+ const apiProvider = useMemo(
58
+ () => {
59
+ switch (flexMenuApiProvider?.toLowerCase()) {
60
+ //case AsistServerProviderName:
61
+ // return new AsistServerApiProvider.from(timetableApiBaseUrl, timetableApiUniversity, 'de');
62
+ // break;
63
+ case CollectorVersion2ProviderName:
64
+ return new CollectorVersion2ApiProvider.from(flexMenuApiBaseUrl);
65
+ break;
66
+ default:
67
+ console.log(`${componentName}: Can't build api provider: ${flexMenuApiProvider}`)
68
+ return null;
69
+ }
70
+ },
71
+ [flexMenuApiProvider, flexMenuApiBaseUrl]
72
+ );
73
+
74
+ const refreshMenuEntries = useCallback(
75
+ () =>
76
+ apiProvider?.getMenuEntries()
77
+ .then(setMenuEntries)
78
+ .catch(reason => console.error(componentName, ':', 'Error while updating menu entries', ':', reason)),
79
+ [apiProvider, setMenuEntries]
80
+ );
81
+
82
+ // Aktualiseren des menuEntries-States
83
+ useEffect(
84
+ () => {
85
+ refreshMenuEntries();
86
+ },
87
+ [refreshMenuEntries]
88
+ );
89
+
90
+ // Speichert die geänderten Menüpunkte in den Store
91
+ useEffect(
92
+ () => {
93
+ if (menuEntries) {
94
+ AsyncStorage.setItem(MenuEntriesStoreKey, JSON.stringify(menuEntries))
95
+ .catch(reason => console.error(`${componentName}: Error while safing courses in store: ${reason}`));
96
+ }
97
+ },
98
+ [menuEntries]
99
+ );
100
+
101
+ return (
102
+ <FlexMenuContext.Provider
103
+ value={{
104
+ menuEntries,
105
+ refreshMenuEntries,
106
+ }}
107
+ >
108
+ {children}
109
+ </FlexMenuContext.Provider>
110
+ )
111
+
112
+ }
113
+
114
+ function useFlexMenuContext() {
115
+ return useContext(FlexMenuContext);
116
+ }
117
+
118
+ function useMenuEntries() {
119
+ const { menuEntries, refreshMenuEntries } = useFlexMenuContext();
120
+
121
+ return [
122
+ Array.isArray(menuEntries)
123
+ ? menuEntries
124
+ : [],
125
+ refreshMenuEntries
126
+ ];
127
+ }
128
+
129
+ function useChildMenuEntries(parentMenuId) {
130
+ const [menuEntries, refreshMenuEntries] = useMenuEntries();
131
+
132
+ // Alle Menüeinträge nach der parentMenuId filtern
133
+ const childMenuEntries = menuEntries.filter(
134
+ // Die Eltern-ID des zu filternden Menüeintrages wird in die Pfad-Segmente zerlegt und das letzte Segment zum vergleichen genommen.
135
+ // Falls Eltern-ID im zu filternden Menüeintrages nicht vorhanden, wird null als Ersatzwert verwendet.
136
+ menuEntry => parentMenuId === (menuEntry?.parentMenuEntry?.split?.('/')?.filter?.(urlSegment => urlSegment !== '')?.pop?.() ?? null)
137
+ );
138
+
139
+ return [childMenuEntries, refreshMenuEntries]
140
+ }
141
+
142
+ /**
143
+ * Es werden alle Hauptmenüeinträge zurückgegeben, wobei Menueinträge ohne Eltern-ID sind Hauptmenüeinträge
144
+ * @returns {[MenuEntry[], () => void]}
145
+ * @example
146
+ * const [mainMenuEntries, refreshMenuEntries] = useMainMenuEntries();
147
+ */
148
+ function useMainMenuEntries() {
149
+ // Menueinträge ohne Eltern-ID sind Hauptmenüeinträge
150
+ return useChildMenuEntries(null);
151
+ }
152
+
153
+ export {
154
+ FlexMenuContext as default,
155
+ FlexMenuContextProvider,
156
+ useFlexMenuContext,
157
+ useMenuEntries,
158
+ useChildMenuEntries,
159
+ useMainMenuEntries,
160
+ }
@@ -0,0 +1,53 @@
1
+ import HttpApiProvider from '../../libraries/base-api-provider';
2
+
3
+ /**
4
+ * Infos-API-Client für Kollektor
5
+ */
6
+ export default class CollektorVersion2ApiProvider extends HttpApiProvider {
7
+
8
+ /**
9
+ * @param {string} baseUrl URL des Kollektors
10
+ * @param {string[]} acceptingLanguages Liste der akzeptierten Sprachen die dem Kollektor mitgesendet werden, dabei ist die Priorität die Reihenfolge.
11
+ */
12
+ constructor(baseUrl, acceptingLanguages) {
13
+ // ContentTypes wird auf JSON festgesetzt, da der Kollektor nur JSON spricht.
14
+ super(baseUrl, acceptingLanguages, ['application/json']);
15
+ }
16
+
17
+ /**
18
+ * Erstellt und gibt die abzufragende URL für die Abfrage aller Infos zurück.
19
+ *
20
+ * @returns {URL} URL für die Abfrage aller Infos-Objekte.
21
+ */
22
+ getInfosUrl() {
23
+ const getInfoUrl = this.extendBaseUrl(['infos']);
24
+
25
+ return getInfoUrl
26
+ }
27
+
28
+ /**
29
+ * Gibt die Liste aller Info-Objekte zurück.
30
+ *
31
+ * @returns {Array} Liste aller Info-Objekte.
32
+ */
33
+ getInfos() {
34
+ const getInfosUrl = this.getInfosUrl();
35
+
36
+ return this.get(getInfosUrl)
37
+ .then(response => response.json());
38
+ }
39
+
40
+ /**
41
+ * Erstellt eine CollektorVersion2ApiProvider-Instanz, welche Englisch und Deutsch initialisiert wird.
42
+ * Die priorisierte Hauptsprache kann als Paramter übergeben werden.
43
+ *
44
+ * @param {string} baseUrl URL des Kollektors
45
+ * @param {string} [mainLanguage='de'] Hauptsprache, welche priorisiert wird.
46
+ * @returns {CollektorVersion2ApiProvider} Erstellte CollektorVersion2ApiProvider-Instanz
47
+ */
48
+ static from(baseUrl, mainLanguage = 'de') {
49
+ const acceptingLanguages = CollektorVersion2ApiProvider.languagesFromMainLanguages(mainLanguage);
50
+
51
+ return new CollektorVersion2ApiProvider(baseUrl, acceptingLanguages);
52
+ }
53
+ }
@@ -0,0 +1,22 @@
1
+
2
+ /**
3
+ * Diese Exception wird ausgelöst, wenn zu dem Studenplancode kein Stundenplan abgeholt werden kann.
4
+ */
5
+ export class TimetableNotFoundError extends Error {
6
+
7
+ /**
8
+ * Stundenplancode welcher keinem Stundenplan angehörig ist.
9
+ * @type {string}
10
+ */
11
+ timetableCode
12
+
13
+ /**
14
+ *
15
+ * @param {string} timetableCode Stundenplancode, welcher zu einem Fehler führte, weil dieser mit keinem Stundenplan verknüpft ist
16
+ */
17
+ constructor(timetableCode) {
18
+ super(`Timetable code ${timetableCode} is not linked to a timetable`);
19
+ this.timetableCode = timetableCode;
20
+ this.name = this.constructor.name;
21
+ }
22
+ }