@olea-bps/base 1.1.11 → 1.1.12
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.
- package/components/ComponentJobsFilter/index.js +2 -1
- package/components/NewsListItem/index.js +77 -64
- package/components/NewsListItem/styles.js +34 -31
- package/components/TabBarIcon/index.js +35 -0
- package/components/TimetableWeek/styles.js +56 -56
- package/context/context-canteen/index.js +526 -498
- package/context/context-user/index.js +49 -64
- package/index.js +1 -0
- package/package.json +1 -1
- package/views/PublicTransportTicket/index.js +31 -3
- package/views/SettingsAppInfo/index.js +69 -50
- package/views/SettingsAppInfo/styles.js +25 -16
- package/views/SettingsUser/index.js +1 -1
|
@@ -12,18 +12,18 @@
|
|
|
12
12
|
* limitations under the License.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { createContext, useCallback, useEffect, useContext, useReducer, useMemo } from 'react'
|
|
15
|
+
import { createContext, useCallback, useEffect, useContext, useReducer, useMemo, useState } from 'react'
|
|
16
16
|
import { connect, useDispatch, useSelector } from 'react-redux'
|
|
17
|
-
import { useTheme } from 'react-native-paper'
|
|
17
|
+
import { useTheme } from 'react-native-paper'
|
|
18
18
|
import AsyncStorage from '@react-native-async-storage/async-storage'
|
|
19
|
-
import { DateTime } from 'luxon'
|
|
19
|
+
import { DateTime } from 'luxon'
|
|
20
20
|
|
|
21
|
-
import { onSettingCanteenMerge, useStagingServer } from '../../libraries/core'
|
|
22
|
-
import { useUser } from '../context-user'
|
|
23
|
-
import { intersection } from 'lodash'
|
|
21
|
+
import { onSettingCanteenMerge, useStagingServer } from '../../libraries/core'
|
|
22
|
+
import { useUser } from '../context-user'
|
|
23
|
+
import { intersection } from 'lodash'
|
|
24
24
|
|
|
25
|
-
import CollektorVersion2ApiProvider, { NotModifiedResponse } from './CollektorVersion2ApiProvider.js'
|
|
26
|
-
import AsistServerApiProvider from './AsistServerApiProvider.js'
|
|
25
|
+
import CollektorVersion2ApiProvider, { NotModifiedResponse } from './CollektorVersion2ApiProvider.js'
|
|
26
|
+
import AsistServerApiProvider from './AsistServerApiProvider.js'
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* @typedef {Object} Canteen
|
|
@@ -34,23 +34,27 @@ import AsistServerApiProvider from './AsistServerApiProvider.js';
|
|
|
34
34
|
* @typedef {Object.<string, Canteen>} CanteenState
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
|
-
const AsistServerProviderName = 'asist-server'
|
|
38
|
-
const CollectorVersion2ProviderName = 'hs-collector-v2'
|
|
37
|
+
const AsistServerProviderName = 'asist-server'
|
|
38
|
+
const CollectorVersion2ProviderName = 'hs-collector-v2'
|
|
39
39
|
|
|
40
40
|
// Create a context for the canteen data
|
|
41
41
|
const CanteenContext = createContext({
|
|
42
|
-
|
|
43
|
-
})
|
|
42
|
+
canteens: {}
|
|
43
|
+
})
|
|
44
44
|
|
|
45
|
-
const CanteensStoreKey = 'canteen:canteens'
|
|
45
|
+
const CanteensStoreKey = 'canteen:canteens'
|
|
46
46
|
const FavoriteCanteensStoreKey = 'canteen:favorite_canteens'
|
|
47
47
|
|
|
48
|
-
const RestoreCanteens = 'restore_canteens'
|
|
49
|
-
const SetMenuAction = 'set_menu'
|
|
50
|
-
const SetCanteenAction = 'set_canteen'
|
|
48
|
+
const RestoreCanteens = 'restore_canteens'
|
|
49
|
+
const SetMenuAction = 'set_menu'
|
|
50
|
+
const SetCanteenAction = 'set_canteen'
|
|
51
51
|
const RemoveUnusedCanteensAction = 'remove_unused_canteens'
|
|
52
52
|
const RemoveUnusedMenusAction = 'remove_unused_menus'
|
|
53
53
|
|
|
54
|
+
function hasCanteenTitle (canteen) {
|
|
55
|
+
return typeof canteen?.title === 'string' && canteen.title.trim().length > 0
|
|
56
|
+
}
|
|
57
|
+
|
|
54
58
|
/**
|
|
55
59
|
*
|
|
56
60
|
* @param {CanteenState} state
|
|
@@ -58,92 +62,105 @@ const RemoveUnusedMenusAction = 'remove_unused_menus'
|
|
|
58
62
|
* @param {string} action.type
|
|
59
63
|
* @returns {CanteenState}
|
|
60
64
|
*/
|
|
61
|
-
function CanteensStateReducer(state, action) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Anhand eines Datums werden alte Mensen entfernt
|
|
90
|
-
case RemoveUnusedMenusAction: {
|
|
91
|
-
const expiryDate = action.expiryDate;
|
|
92
|
-
const expiryTimestamp = Date.parse(expiryDate);
|
|
93
|
-
|
|
94
|
-
return Object.fromEntries(
|
|
95
|
-
Object.entries(state ?? {})
|
|
96
|
-
.map(
|
|
97
|
-
([canteenId, canteenData]) =>
|
|
98
|
-
[
|
|
99
|
-
canteenId,
|
|
100
|
-
{
|
|
101
|
-
...canteenData,
|
|
102
|
-
menus: Object.fromEntries(
|
|
103
|
-
Object.entries(canteenData?.menus ?? {})
|
|
104
|
-
.filter(([menuDate, menu]) => Date.parse(menuDate) >= expiryTimestamp)
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
)
|
|
109
|
-
);
|
|
65
|
+
function CanteensStateReducer (state, action) {
|
|
66
|
+
switch (action.type) {
|
|
67
|
+
// Essensangebot einer Mensa zuordnen
|
|
68
|
+
case SetMenuAction: {
|
|
69
|
+
const canteenId = action.canteenId
|
|
70
|
+
const menuDate = action.date
|
|
71
|
+
const menu = action.menu
|
|
72
|
+
|
|
73
|
+
if (hasCanteenTitle(state?.[canteenId])) {
|
|
74
|
+
// Einfügen des Essensangebot(menu) für eine Mensa(canteenId) an einem Tag(menuDate)
|
|
75
|
+
return {
|
|
76
|
+
// Kopieren der vorherigen Mensen
|
|
77
|
+
...state ?? {},
|
|
78
|
+
// Bestehende Mensa aktualisieren
|
|
79
|
+
[canteenId]: {
|
|
80
|
+
// Kopieren der vorherigen Daten der Mense
|
|
81
|
+
...state?.[canteenId] ?? {},
|
|
82
|
+
// Essensangebote werden neu erstellt
|
|
83
|
+
menus: {
|
|
84
|
+
// Kopieren der alten Essensangebote
|
|
85
|
+
...state?.[canteenId]?.menus ?? {},
|
|
86
|
+
// Es wird das Essensangebote(menu) für ein Datum(menuDate) hinterlegt
|
|
87
|
+
[menuDate]: menu
|
|
88
|
+
}
|
|
89
|
+
}
|
|
110
90
|
}
|
|
91
|
+
} else {
|
|
92
|
+
// Late menu responses must not recreate a canteen removed by the server list.
|
|
93
|
+
return state
|
|
94
|
+
}
|
|
95
|
+
}
|
|
111
96
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
97
|
+
// Anhand eines Datums werden alte Mensen entfernt
|
|
98
|
+
case RemoveUnusedMenusAction: {
|
|
99
|
+
const expiryDate = action.expiryDate
|
|
100
|
+
const expiryTimestamp = Date.parse(expiryDate)
|
|
101
|
+
|
|
102
|
+
return Object.fromEntries(
|
|
103
|
+
Object.entries(state ?? {})
|
|
104
|
+
.map(
|
|
105
|
+
([canteenId, canteenData]) =>
|
|
106
|
+
[
|
|
107
|
+
canteenId,
|
|
108
|
+
{
|
|
109
|
+
...canteenData,
|
|
110
|
+
menus: Object.fromEntries(
|
|
111
|
+
Object.entries(canteenData?.menus ?? {})
|
|
112
|
+
.filter(([menuDate, menu]) => Date.parse(menuDate) >= expiryTimestamp)
|
|
113
|
+
)
|
|
121
114
|
}
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
]
|
|
116
|
+
)
|
|
117
|
+
)
|
|
118
|
+
}
|
|
124
119
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
120
|
+
// Es werden die Basisdaten einer Mensa hinzugefügt oder aktualisiert
|
|
121
|
+
case SetCanteenAction: {
|
|
122
|
+
const canteen = action.canteen
|
|
128
123
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
124
|
+
return {
|
|
125
|
+
...state ?? {},
|
|
126
|
+
[canteen.id]: {
|
|
127
|
+
...state?.[canteen.id] ?? {},
|
|
128
|
+
...canteen
|
|
133
129
|
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
// Anhand einer Liste von Mensa-IDs werden alte Mensen entfernt
|
|
134
|
+
case RemoveUnusedCanteensAction: {
|
|
135
|
+
const activeCanteenIds = action.activeCanteenIds.map(String)
|
|
138
136
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
return Object.fromEntries(
|
|
138
|
+
Object.entries(state ?? {})
|
|
139
|
+
.filter(([canteenId, canteenData]) => activeCanteenIds.includes(canteenId))
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Mensen und zugehörige Essensangebote aus dem Cache wiederherstellen
|
|
144
|
+
case RestoreCanteens: {
|
|
145
|
+
// Remove incomplete entries persisted by older app versions, also offline.
|
|
146
|
+
// Entries are considered incomplete if their canteen title is missing or blank.
|
|
147
|
+
const restoredCanteens = Object.fromEntries(
|
|
148
|
+
Object.entries(action.canteens ?? {})
|
|
149
|
+
.filter(([, canteen]) => hasCanteenTitle(canteen))
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
return state
|
|
153
|
+
? { ...state }
|
|
154
|
+
: restoredCanteens
|
|
143
155
|
}
|
|
156
|
+
|
|
157
|
+
default:
|
|
158
|
+
// Preserve the current state for unhandled actions instead of returning undefined.
|
|
159
|
+
return state
|
|
160
|
+
}
|
|
144
161
|
}
|
|
145
162
|
|
|
146
|
-
const SetCanteensAction = 'set_canteens_ids'
|
|
163
|
+
const SetCanteensAction = 'set_canteens_ids'
|
|
147
164
|
|
|
148
165
|
/**
|
|
149
166
|
*
|
|
@@ -152,35 +169,36 @@ const SetCanteensAction = 'set_canteens_ids';
|
|
|
152
169
|
* @param {string} action.type
|
|
153
170
|
* @returns {string[]}
|
|
154
171
|
*/
|
|
155
|
-
function FavoriteCanteensStateReducer(state, action) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
172
|
+
function FavoriteCanteensStateReducer (state, action) {
|
|
173
|
+
switch (action.type) {
|
|
174
|
+
// Setzen der IDs der favoriten Mensen
|
|
175
|
+
case SetCanteensAction: {
|
|
176
|
+
const canteensIds = Array.isArray(action?.canteensIds) && action.canteensIds.length > 0
|
|
177
|
+
? [...new Set(action.canteensIds.map(String))]
|
|
178
|
+
: null
|
|
179
|
+
|
|
180
|
+
return canteensIds
|
|
181
|
+
}
|
|
164
182
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
183
|
+
// Filtert IDs aus der Einstellung heraus, welche nicht mehr vom Kollektor übersendet werden
|
|
184
|
+
case RemoveUnusedCanteensAction: {
|
|
185
|
+
const activeCanteenIds = action.activeCanteenIds.map(String)
|
|
168
186
|
|
|
169
|
-
|
|
187
|
+
const favoriteCanteensIds = intersection(state, activeCanteenIds)
|
|
170
188
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
189
|
+
return Array.isArray(favoriteCanteensIds) && favoriteCanteensIds.length > 0
|
|
190
|
+
? favoriteCanteensIds
|
|
191
|
+
: null
|
|
192
|
+
}
|
|
175
193
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
194
|
+
// Falls ein unbekannter Actionstyp übergeben wurde, wird nichts gemacht
|
|
195
|
+
default: {
|
|
196
|
+
return state
|
|
180
197
|
}
|
|
198
|
+
}
|
|
181
199
|
}
|
|
182
200
|
|
|
183
|
-
//const providersInitializers = {
|
|
201
|
+
// const providersInitializers = {
|
|
184
202
|
// 'hs-collector-v2': ({appSettings }) => {
|
|
185
203
|
// const baseUrl = appSettings?.modules?.canteen?.api?.baseUrl;
|
|
186
204
|
// CollektorVersion2ApiProvider.from(baseUrl,)
|
|
@@ -188,359 +206,369 @@ function FavoriteCanteensStateReducer(state, action) {
|
|
|
188
206
|
// 'asist-server': ({ }) => {
|
|
189
207
|
//
|
|
190
208
|
// },
|
|
191
|
-
//}
|
|
209
|
+
// }
|
|
192
210
|
|
|
193
211
|
// Define a provider component for the canteen context
|
|
194
|
-
function CanteenContextProvider({ children, settings, rootUrl, rootStgUrl, useStaging }) {
|
|
195
|
-
|
|
212
|
+
function CanteenContextProvider ({ children, settings, rootUrl, rootStgUrl, useStaging }) {
|
|
213
|
+
const componentName = CanteenContextProvider.name
|
|
196
214
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
215
|
+
const reduxDispatch = useDispatch()
|
|
216
|
+
const [user] = useUser()
|
|
217
|
+
const theme = useTheme()
|
|
200
218
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
219
|
+
const appSettings = theme?.appSettings
|
|
220
|
+
const groupsOfPersons = appSettings?.groupsOfPersons
|
|
221
|
+
const language = settings.language
|
|
222
|
+
const availableSelections = theme?.appSettings?.mealSelections
|
|
223
|
+
const favoriteSelections = settings?.settingsCanteens?.favoriteSelection
|
|
206
224
|
|
|
207
|
-
|
|
208
|
-
|
|
225
|
+
// Ermitteln des Preisgruppen-Codes des Nutzers
|
|
226
|
+
const priceGroupCode =
|
|
209
227
|
// Wenn der Nutzer selber eine Preisgruppe festgelegt hast, ist diese im Redux hinterlegt
|
|
210
228
|
// Prüfen ob im Redux eine Preisgruppe hinterlegt ist
|
|
211
229
|
useSelector(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
)
|
|
230
|
+
(reduxState) =>
|
|
231
|
+
// Wenn der Preisgruppen-Code ein leerer String ist, wird stattdessen null zurückgegeben
|
|
232
|
+
reduxState?.settingReducer?.settingsCanteens?.favoritePrice
|
|
233
|
+
? reduxState?.settingReducer?.settingsCanteens?.favoritePrice
|
|
234
|
+
: null
|
|
235
|
+
) ??
|
|
218
236
|
// Ist im Redux keine Preisgruppe hinterlegt, wird anhand des angemeldeten Nutzers die Preisgruppe ermittelt
|
|
219
237
|
// Dabei werden die Angehörigkeiten(user.member_types) des Nutzer mit den möglichen Personengruppen-Codes verglichen
|
|
220
238
|
// Ist eine Angehörigkeit, welche einem Code einer Personengruppe gleicht, vorhanden, wird die entsprechende Personengruppe verwendet
|
|
221
239
|
// Besitzt ein Nutzer mehrer Angehörigkeiten (z.B. Student, Mitarbeiter) wird anhand der Reihenfolge der Personengruppen in der Settings.js priorisiert.
|
|
222
240
|
// Dabei besetzt die erste bzw. oberste Personengruppe die höchste Priorität
|
|
223
|
-
|
|
241
|
+
groupsOfPersons.find((personGroup) => user?.member_types?.includes?.(personGroup?.code))?.code ??
|
|
224
242
|
// Wenn der Nutzer nicht eingeloogt ist oder durch den Angehörigkeiten keine Personengruppe ermittelt werden konnt, wird die Standartgruppe ausgewählt
|
|
225
243
|
// Bei der Standartpersonengruppe ist in der Sttings.js das 'default'-Feld auf Wahr/true gesetzt.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
244
|
+
groupsOfPersons.find(personGroup => personGroup?.default)?.code
|
|
245
|
+
|
|
246
|
+
// Daten für Essenstypen
|
|
247
|
+
const availableMealTypes = theme?.appSettings?.mealTypes
|
|
248
|
+
const favoriteMealTypes = settings?.settingsCanteens?.favoriteMealTypes
|
|
249
|
+
|
|
250
|
+
// Einstellung für Serverauswahl
|
|
251
|
+
const isStagingServerActive = useStagingServer()
|
|
252
|
+
|
|
253
|
+
// Einstellungen für Mensa-Modul
|
|
254
|
+
const canteenSettings = appSettings?.modules?.canteen
|
|
255
|
+
|
|
256
|
+
// Einstellungen für Fallback API-Provider
|
|
257
|
+
const fallbackApiSettings = theme?.appSettings?.api
|
|
258
|
+
const fallbackApiProvider = AsistServerProviderName
|
|
259
|
+
const fallbackApiBaseUrl = (isStagingServerActive ? fallbackApiSettings.rootStgUrl : fallbackApiSettings.rootUrl) + 'app/'
|
|
260
|
+
const fallbbackApiUniversity = fallbackApiSettings?.university
|
|
261
|
+
|
|
262
|
+
// Einstellungen für API-Provider
|
|
263
|
+
const canteenApiSettings = canteenSettings.api
|
|
264
|
+
// Soll der Staging-Provider verwendet werden?
|
|
265
|
+
const canteenApiProviderSettings = isStagingServerActive
|
|
266
|
+
// Wenn ja, werden die Staging Provider-Einstellungen geladen
|
|
267
|
+
? canteenApiSettings?.staging
|
|
268
|
+
// Wenn nein, werden die productiven Provider-Einstellungen geladen
|
|
269
|
+
: canteenApiSettings?.production
|
|
270
|
+
const canteenApiProvider = canteenApiProviderSettings?.provider ?? fallbackApiProvider
|
|
271
|
+
const canteenApiBaseUrl = canteenApiProviderSettings?.url ?? fallbackApiBaseUrl
|
|
272
|
+
const canteenApiUniversity = canteenApiProviderSettings?.university ?? fallbbackApiUniversity
|
|
273
|
+
|
|
274
|
+
const [canteens, dispatchCanteens] = useReducer(CanteensStateReducer, null)
|
|
275
|
+
const [favoriteCanteens, dispatchFavoriteCanteens] = useReducer(FavoriteCanteensStateReducer, null)
|
|
276
|
+
const [cacheRestored, setCacheRestored] = useState(false)
|
|
277
|
+
|
|
278
|
+
// Einmaliges Laden der gecachten Mensadaten und der zugehörigen Speisepläne aus dem Cache in den Kontext
|
|
279
|
+
useEffect(
|
|
280
|
+
() => {
|
|
281
|
+
let active = true
|
|
282
|
+
const restoreCanteens = AsyncStorage
|
|
283
|
+
.getItem(CanteensStoreKey)
|
|
284
|
+
.then(storedCanteens => {
|
|
285
|
+
if (!active) return
|
|
286
|
+
dispatchCanteens({ type: RestoreCanteens, canteens: JSON.parse(storedCanteens) })
|
|
287
|
+
dispatchCanteens({ type: RemoveUnusedMenusAction, expiryDate: DateTime.now().minus({ weeks: 1 }).endOf('week').toISODate() })
|
|
288
|
+
})
|
|
289
|
+
.catch(reason => console.error(componentName, ':', 'can not restore canteens', ':', reason, 'key', ':', CanteensStoreKey))
|
|
290
|
+
|
|
291
|
+
const restoreFavorites = AsyncStorage
|
|
292
|
+
.getItem(FavoriteCanteensStoreKey)
|
|
293
|
+
.then(storedFavoriteCanteens => {
|
|
294
|
+
if (!active) return
|
|
295
|
+
dispatchFavoriteCanteens({ type: SetCanteensAction, canteensIds: JSON.parse(storedFavoriteCanteens) })
|
|
296
|
+
})
|
|
297
|
+
.catch(reason => console.error(componentName, ':', 'can not restore favorite canteens ids', ':', reason, 'key', ':', FavoriteCanteensStoreKey))
|
|
298
|
+
|
|
299
|
+
// The server list must reconcile both restored caches, never race them.
|
|
300
|
+
Promise.all([restoreCanteens, restoreFavorites]).then(() => {
|
|
301
|
+
if (active) setCacheRestored(true)
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
return () => { active = false }
|
|
305
|
+
}
|
|
306
|
+
, []
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
// Wenn die Mensa-Daten sich ändern, werden diese in den Cache zurückgespeichert
|
|
310
|
+
useEffect(
|
|
311
|
+
() => {
|
|
312
|
+
if (cacheRestored && canteens) {
|
|
313
|
+
AsyncStorage
|
|
314
|
+
.setItem(CanteensStoreKey, JSON.stringify(canteens))
|
|
315
|
+
.catch(reason => console.error(componentName, ':', 'can`t store canteens: ', reason, 'key:', CanteensStoreKey, 'value:', canteens))
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
, [cacheRestored, canteens]
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
// Wenn die favorisirten Mensen sich ändern, werden diese in den Cache zurückgespeichert
|
|
322
|
+
useEffect(
|
|
323
|
+
() => {
|
|
324
|
+
if (cacheRestored) {
|
|
325
|
+
console.debug(componentName, ':', 'store favorite canteens', favoriteCanteens)
|
|
326
|
+
AsyncStorage
|
|
327
|
+
.setItem(FavoriteCanteensStoreKey, JSON.stringify(favoriteCanteens))
|
|
328
|
+
.catch(reason => console.error(componentName, ':', 'can`t store canteens: ', reason, 'key:', FavoriteCanteensStoreKey, 'value:', favoriteCanteens))
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
[cacheRestored, favoriteCanteens]
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
console.debug(componentName, ':', 'favorite selections', ':', favoriteSelections)
|
|
335
|
+
console.debug(componentName, ':', 'available selections', ':', availableSelections)
|
|
336
|
+
|
|
337
|
+
const activeSelections = useMemo(
|
|
338
|
+
() => {
|
|
339
|
+
if (Array.isArray(favoriteSelections) && favoriteSelections.length > 0 && Array.isArray(availableSelections)) {
|
|
340
|
+
return availableSelections
|
|
341
|
+
.filter(availableSelection => favoriteSelections.includes(availableSelection.code))
|
|
342
|
+
} else {
|
|
343
|
+
return null
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
[favoriteSelections, availableSelections]
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
console.debug(componentName, ':', 'active selections', ':', activeSelections)
|
|
350
|
+
|
|
351
|
+
const activeSelectionFilters = useMemo(
|
|
352
|
+
() => {
|
|
353
|
+
if (Array.isArray(activeSelections) && activeSelections.length > 0) {
|
|
354
|
+
return [
|
|
355
|
+
...new Set(
|
|
356
|
+
activeSelections
|
|
357
|
+
.flatMap(activeSelection => activeSelection?.filters)
|
|
358
|
+
)
|
|
359
|
+
]
|
|
360
|
+
} else {
|
|
361
|
+
return null
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
[activeSelections]
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
console.debug(componentName, ':', 'active selection filter', ':', activeSelectionFilters)
|
|
368
|
+
|
|
369
|
+
console.debug(componentName, ':', 'available meal typeas', ':', availableMealTypes)
|
|
370
|
+
console.debug(componentName, ':', 'favorite meal types', ':', favoriteMealTypes)
|
|
371
|
+
|
|
372
|
+
const activeMealtypes = useMemo(
|
|
373
|
+
() => {
|
|
374
|
+
if (Array.isArray(favoriteMealTypes) && favoriteMealTypes.length > 0 && Array.isArray(availableMealTypes)) {
|
|
375
|
+
return availableMealTypes
|
|
376
|
+
.filter(activeMealtype => favoriteMealTypes.includes(activeMealtype.code))
|
|
377
|
+
} else {
|
|
378
|
+
return null
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
[favoriteMealTypes, availableMealTypes]
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
console.debug(componentName, ':', 'active meal types', ':', activeMealtypes)
|
|
385
|
+
|
|
386
|
+
const activeMealtypeFilters = useMemo(
|
|
387
|
+
() => {
|
|
388
|
+
if (Array.isArray(activeMealtypes) && activeMealtypes.length > 0) {
|
|
389
|
+
return [
|
|
390
|
+
...new Set(
|
|
391
|
+
activeMealtypes
|
|
392
|
+
.flatMap(activeMealtype => activeMealtype?.filters ?? activeMealtype?.code ?? [])
|
|
393
|
+
)
|
|
394
|
+
]
|
|
395
|
+
} else {
|
|
396
|
+
return null
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
console.debug(componentName, ':', 'active meal type filters', ':', activeMealtypeFilters)
|
|
402
|
+
|
|
403
|
+
// Estellen des API-Providers bzw. erneuern wenn sich Einstellungen sich ändern.
|
|
404
|
+
const apiProvider = useMemo(
|
|
405
|
+
() => {
|
|
406
|
+
switch (canteenApiProvider?.toLowerCase()) {
|
|
407
|
+
case AsistServerProviderName:
|
|
408
|
+
console.debug(componentName, ': use asist server api')
|
|
409
|
+
return AsistServerApiProvider.from(canteenApiBaseUrl, canteenApiUniversity, language)
|
|
410
|
+
case CollectorVersion2ProviderName:
|
|
411
|
+
console.debug(componentName, ': use collector v2 api')
|
|
412
|
+
return CollektorVersion2ApiProvider.from(canteenApiBaseUrl, language)
|
|
413
|
+
default:
|
|
414
|
+
console.log(`${componentName}: Can't build api provider: ${canteenApiProvider}`)
|
|
415
|
+
return null
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
[canteenApiSettings, canteenApiProvider, canteenApiBaseUrl, canteenApiUniversity, language]
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
// Sobald der Mensa-Context erstellt wird, werden die Mensen vom Server geholt
|
|
422
|
+
useEffect(
|
|
423
|
+
() => {
|
|
424
|
+
let active = true
|
|
425
|
+
if (apiProvider && cacheRestored) {
|
|
426
|
+
apiProvider.getCanteens()
|
|
427
|
+
.then(
|
|
428
|
+
canteens => {
|
|
429
|
+
if (!active) return
|
|
430
|
+
if (!Array.isArray(canteens) || canteens.some(canteen => canteen?.id == null || !hasCanteenTitle(canteen))) {
|
|
431
|
+
throw new Error('Invalid canteen list')
|
|
432
|
+
}
|
|
433
|
+
// Jede Mensa wird einzeln in den Mensa-State hineinreduziert
|
|
434
|
+
canteens.forEach(canteen => dispatchCanteens({ type: SetCanteenAction, canteen }))
|
|
435
|
+
|
|
436
|
+
// Danach werden die alten Mensen, die nicht in der Serverantwort sind, herausreduziert
|
|
437
|
+
// Liste der IDs der in der Serverantwort enthaltenen Mensen erstellen
|
|
438
|
+
const activeCanteenIds = canteens.map(canteen => canteen?.id)
|
|
439
|
+
// Alte Mensen aus den gecachten Mensa-Daten löschen
|
|
440
|
+
dispatchCanteens(
|
|
441
|
+
{
|
|
442
|
+
type: RemoveUnusedCanteensAction,
|
|
443
|
+
activeCanteenIds
|
|
444
|
+
}
|
|
445
|
+
)
|
|
446
|
+
// Alte Mensen aus den favorisierten Mensen löschen
|
|
447
|
+
dispatchFavoriteCanteens(
|
|
448
|
+
{
|
|
449
|
+
type: RemoveUnusedCanteensAction,
|
|
450
|
+
activeCanteenIds
|
|
451
|
+
}
|
|
452
|
+
)
|
|
430
453
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
454
|
+
)
|
|
455
|
+
.catch(reason => console.warn(componentName, ':', 'can not refresh canteens', ':', reason))
|
|
456
|
+
}
|
|
457
|
+
return () => { active = false }
|
|
458
|
+
},
|
|
459
|
+
[apiProvider, cacheRestored]
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
/**
|
|
436
463
|
* Refresh a menu in canteens object.
|
|
437
464
|
*
|
|
438
465
|
* @param {String} canteenId ID of the canteen of the menu to be refreshing
|
|
439
466
|
* @param {String} date Date of the menu to be refreshing
|
|
440
467
|
* @returns {Promise<void>} Promise as an indicator of whether the refresh is in progress
|
|
441
468
|
*/
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
469
|
+
function refreshMenu (canteenId, date) {
|
|
470
|
+
return apiProvider.getMenu(canteenId, date)
|
|
471
|
+
.then(
|
|
472
|
+
menu =>
|
|
473
|
+
dispatchCanteens(
|
|
474
|
+
{
|
|
475
|
+
type: SetMenuAction,
|
|
476
|
+
menu,
|
|
477
|
+
canteenId,
|
|
478
|
+
date
|
|
479
|
+
}
|
|
480
|
+
),
|
|
481
|
+
reason => {
|
|
482
|
+
if (reason instanceof NotModifiedResponse) {
|
|
483
|
+
console.debug(componentName, ':', 'Meal from', date, 'and canteen', canteenId, 'not modified')
|
|
484
|
+
} else {
|
|
485
|
+
// Keep cached menus when a request fails (e.g. a removed ID).
|
|
486
|
+
console.warn(componentName, ':', 'can not refresh menu', canteenId, date, ':', reason)
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
)
|
|
490
|
+
}
|
|
463
491
|
|
|
464
|
-
|
|
492
|
+
/**
|
|
465
493
|
* Setz den vom Nutzer gewünschen Mensapreis, anhand des Codes der entsprechnden Personengruppe.
|
|
466
494
|
* @function
|
|
467
495
|
* @param {string} personGroupCode Code der Personengruppe, welche für die Mensapreise zu verwenden ist
|
|
468
496
|
*/
|
|
469
|
-
|
|
470
|
-
|
|
497
|
+
const setPriceGroupCode = useCallback(
|
|
498
|
+
/**
|
|
471
499
|
* @param {string} personGroupCode Code der Personengruppe, welche für die Mensapreise zu verwenden ist
|
|
472
500
|
*/
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
501
|
+
(personGroupCode) =>
|
|
502
|
+
reduxDispatch(
|
|
503
|
+
onSettingCanteenMerge(
|
|
504
|
+
'canteenSettings',
|
|
505
|
+
{ favoritePrice: personGroupCode }
|
|
506
|
+
)
|
|
507
|
+
),
|
|
508
|
+
[reduxDispatch]
|
|
509
|
+
)
|
|
482
510
|
|
|
483
|
-
|
|
511
|
+
/**
|
|
484
512
|
* Setzt die favorsierten Mensen, anhand einer Liste der IDs
|
|
485
513
|
*/
|
|
486
|
-
|
|
487
|
-
|
|
514
|
+
const setFavoriteCanteens = useCallback(
|
|
515
|
+
/**
|
|
488
516
|
* @param {string[]} favoriteCanteens IDs der Mensen, die als favorisiert gesetzt werden sollen
|
|
489
517
|
*/
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
518
|
+
(favoriteCanteens) => {
|
|
519
|
+
console.debug(componentName, ':', 'set favorite canteens', ':', favoriteCanteens)
|
|
520
|
+
dispatchFavoriteCanteens(
|
|
521
|
+
{
|
|
522
|
+
type: SetCanteensAction,
|
|
523
|
+
canteensIds: favoriteCanteens
|
|
524
|
+
}
|
|
525
|
+
)
|
|
526
|
+
},
|
|
527
|
+
[dispatchFavoriteCanteens, SetCanteensAction]
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
// Render the provider component with the filtered canteens and canteens data
|
|
531
|
+
return (
|
|
532
|
+
<CanteenContext.Provider
|
|
533
|
+
value={{
|
|
534
|
+
canteens: canteens ?? {},
|
|
535
|
+
favoriteCanteens: (favoriteCanteens ?? Object.keys(canteens ?? {}))
|
|
536
|
+
.filter(canteenId => hasCanteenTitle(canteens?.[canteenId])),
|
|
537
|
+
setFavoriteCanteens,
|
|
538
|
+
priceGroupCode,
|
|
539
|
+
setPriceGroupCode,
|
|
540
|
+
activeSelections,
|
|
541
|
+
activeSelectionFilters,
|
|
542
|
+
activeMealtypes,
|
|
543
|
+
activeMealtypeFilters,
|
|
544
|
+
refreshMenu
|
|
545
|
+
}}
|
|
546
|
+
>
|
|
547
|
+
{children}
|
|
548
|
+
</CanteenContext.Provider>
|
|
549
|
+
)
|
|
521
550
|
}
|
|
522
551
|
|
|
523
552
|
// Map the Redux state to props
|
|
524
553
|
const mapStateToProps = storeState => {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
}
|
|
554
|
+
return {
|
|
555
|
+
settings: storeState.settingReducer,
|
|
556
|
+
rootUrl: storeState.settingReducer.api.rootUrl,
|
|
557
|
+
rootStgUrl: storeState.settingReducer.api.rootStgUrl,
|
|
558
|
+
useStaging: storeState.settingReducer.settingsDevelop.useStaging
|
|
559
|
+
}
|
|
560
|
+
}
|
|
532
561
|
|
|
533
562
|
// Connect the CanteenContextProvider component to Redux
|
|
534
|
-
const ConnectedCanteenContextProvider = connect(mapStateToProps)(CanteenContextProvider)
|
|
535
|
-
|
|
563
|
+
const ConnectedCanteenContextProvider = connect(mapStateToProps)(CanteenContextProvider)
|
|
536
564
|
|
|
537
565
|
// Custom hook to use the CanteenContext
|
|
538
|
-
function useCanteenContext() {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
566
|
+
function useCanteenContext () {
|
|
567
|
+
const context = useContext(CanteenContext)
|
|
568
|
+
if (context === undefined) {
|
|
569
|
+
throw new Error('useCanteenContext must be used within a CanteenContextProvider')
|
|
570
|
+
}
|
|
571
|
+
return context
|
|
544
572
|
}
|
|
545
573
|
|
|
546
574
|
/**
|
|
@@ -554,10 +582,10 @@ function useCanteenContext() {
|
|
|
554
582
|
*
|
|
555
583
|
* refreshMenu('1', '2024-12-31');
|
|
556
584
|
*/
|
|
557
|
-
function useCanteens() {
|
|
558
|
-
|
|
585
|
+
function useCanteens () {
|
|
586
|
+
const canteenContext = useCanteenContext()
|
|
559
587
|
|
|
560
|
-
|
|
588
|
+
return [canteenContext.canteens ?? null, canteenContext.refreshMenu]
|
|
561
589
|
}
|
|
562
590
|
|
|
563
591
|
/**
|
|
@@ -566,13 +594,13 @@ function useCanteens() {
|
|
|
566
594
|
* @param {String} canteenId
|
|
567
595
|
* @returns {[?Object, (menuDate: String) => Promise<void>]}
|
|
568
596
|
*/
|
|
569
|
-
function useCanteen(canteenId) {
|
|
570
|
-
|
|
597
|
+
function useCanteen (canteenId) {
|
|
598
|
+
const [canteens, refreshMenu] = useCanteens()
|
|
571
599
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
600
|
+
return [
|
|
601
|
+
canteens?.[canteenId] ?? null, // Holt die Mensa mit der ID canteenId aus dem Mensa-Objekt
|
|
602
|
+
(menuDate) => refreshMenu(canteenId, menuDate) // Erstellt eine Funktion, die das Essen ohne angeben der canteenId aktualisiert
|
|
603
|
+
]
|
|
576
604
|
}
|
|
577
605
|
|
|
578
606
|
/**
|
|
@@ -582,13 +610,13 @@ function useCanteen(canteenId) {
|
|
|
582
610
|
* @param {String} menuDate
|
|
583
611
|
* @returns {[?Object[], () => Promise<void>]}
|
|
584
612
|
*/
|
|
585
|
-
function useMenu(canteenId, menuDate) {
|
|
586
|
-
|
|
613
|
+
function useMenu (canteenId, menuDate) {
|
|
614
|
+
const [canteen, refreshMenu] = useCanteen(canteenId)
|
|
587
615
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
616
|
+
return [
|
|
617
|
+
canteen?.menus?.[menuDate] ?? null, // Holt das Essen aus der Mensa mit der ID canteenId
|
|
618
|
+
() => refreshMenu(menuDate) // Erstellt eine Funktion, die das Essen ohne angeben von canteenId und menuDate aktualisiert
|
|
619
|
+
]
|
|
592
620
|
}
|
|
593
621
|
|
|
594
622
|
/**
|
|
@@ -598,49 +626,49 @@ function useMenu(canteenId, menuDate) {
|
|
|
598
626
|
* @param {String} menuDate
|
|
599
627
|
* @returns {[?Object, () => Promise<void>]}
|
|
600
628
|
*/
|
|
601
|
-
function useFilteredMenu(canteenId, menuDate) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
629
|
+
function useFilteredMenu (canteenId, menuDate) {
|
|
630
|
+
// const hookName = arguments.callee.name;
|
|
631
|
+
// const hookCall = `${hookName}(canteenId: ${canteenId}, menuDate: ${menuDate})`;
|
|
632
|
+
|
|
633
|
+
const {
|
|
634
|
+
activeSelections,
|
|
635
|
+
activeSelectionFilters,
|
|
636
|
+
activeMealtypes,
|
|
637
|
+
activeMealtypeFilters
|
|
638
|
+
} = useCanteenContext()
|
|
639
|
+
const [menu, refreshMenu] = useMenu(canteenId, menuDate)
|
|
640
|
+
|
|
641
|
+
let filteredMenu = menu
|
|
642
|
+
|
|
643
|
+
if (activeSelectionFilters) {
|
|
644
|
+
filteredMenu = filteredMenu?.filter(
|
|
645
|
+
meal => activeSelectionFilters.every(
|
|
646
|
+
activeSelectionFilter => meal.selections.includes(activeSelectionFilter)
|
|
647
|
+
)
|
|
648
|
+
)
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (activeMealtypeFilters) {
|
|
652
|
+
filteredMenu = filteredMenu
|
|
653
|
+
?.filter(
|
|
654
|
+
meal =>
|
|
655
|
+
meal?.type
|
|
656
|
+
? activeMealtypeFilters.includes(meal.type)
|
|
657
|
+
: true
|
|
658
|
+
)
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const mealAmount = menu?.length ?? 0
|
|
662
|
+
const filteredMealAmount = filteredMenu?.length ?? 0
|
|
663
|
+
|
|
664
|
+
return [
|
|
665
|
+
filteredMenu,
|
|
666
|
+
refreshMenu,
|
|
667
|
+
mealAmount,
|
|
668
|
+
filteredMealAmount,
|
|
669
|
+
activeSelections,
|
|
670
|
+
activeMealtypes
|
|
671
|
+
]
|
|
644
672
|
}
|
|
645
673
|
|
|
646
674
|
/**
|
|
@@ -658,10 +686,10 @@ function useFilteredMenu(canteenId, menuDate) {
|
|
|
658
686
|
* console.log(priceGroupCode);
|
|
659
687
|
* setPriceGroupCode('guest');
|
|
660
688
|
*/
|
|
661
|
-
function usePriceGroupCode() {
|
|
662
|
-
|
|
689
|
+
function usePriceGroupCode () {
|
|
690
|
+
const { priceGroupCode, setPriceGroupCode } = useCanteenContext()
|
|
663
691
|
|
|
664
|
-
|
|
692
|
+
return [priceGroupCode, setPriceGroupCode]
|
|
665
693
|
}
|
|
666
694
|
|
|
667
695
|
/**
|
|
@@ -673,20 +701,20 @@ function usePriceGroupCode() {
|
|
|
673
701
|
*
|
|
674
702
|
* setFavoriteCanteens(['canteen1', 'canteen2']);
|
|
675
703
|
*/
|
|
676
|
-
function useFavoriteCanteens() {
|
|
677
|
-
|
|
704
|
+
function useFavoriteCanteens () {
|
|
705
|
+
const { favoriteCanteens, setFavoriteCanteens } = useCanteenContext()
|
|
678
706
|
|
|
679
|
-
|
|
707
|
+
return [favoriteCanteens, setFavoriteCanteens]
|
|
680
708
|
}
|
|
681
709
|
|
|
682
710
|
export {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
}
|
|
711
|
+
ConnectedCanteenContextProvider as CanteenContextProvider,
|
|
712
|
+
CanteenContext as default,
|
|
713
|
+
useCanteenContext,
|
|
714
|
+
useCanteens,
|
|
715
|
+
useCanteen,
|
|
716
|
+
useMenu,
|
|
717
|
+
useFilteredMenu,
|
|
718
|
+
usePriceGroupCode,
|
|
719
|
+
useFavoriteCanteens
|
|
720
|
+
}
|