Skip to content

Commit 34a8d34

Browse files
committed
#837: create new mensa page (mensa2)
1 parent 4d8d5ae commit 34a8d34

10 files changed

+323
-0
lines changed

src/app/app-routing.module.ts

+10
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ const routes: Routes = [
7171
loadChildren: () =>
7272
import('./pages/mensa/mensa.module').then((m) => m.MensaPageModule),
7373
},
74+
{
75+
path: 'mensa2',
76+
loadChildren: () =>
77+
import('./pages/mensa2/mensa2.module').then((m) => m.Mensa2PageModule),
78+
},
7479
{
7580
path: 'news',
7681
loadChildren: () =>
@@ -141,6 +146,11 @@ const routes: Routes = [
141146
(m) => m.LibraryAccountPageModule
142147
),
143148
},
149+
{
150+
path: 'mensa2',
151+
loadChildren: () =>
152+
import('./pages/mensa2/mensa2.module').then((m) => m.Mensa2PageModule),
153+
},
144154
// {
145155
// path: 'events',
146156
// loadChildren: () =>

src/app/pages/mensa2/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Ersetzt die alte Mensa Page (leider haben wir keinen Zugriff mehr auf den Speiseplan der SWP Mensen).
2+
Enthält zwei Tabs: einen Link auf die neue Mensaseite (https://swp.webspeiseplan.de/).
3+
Erhalten bleibt nur eine Übersicht von Speisen und Getränken in Ulfs Kaffee.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { NgModule } from '@angular/core';
2+
import { Routes, RouterModule } from '@angular/router';
3+
4+
import { Mensa2Page } from './mensa2.page';
5+
6+
const routes: Routes = [
7+
{
8+
path: '',
9+
component: Mensa2Page,
10+
},
11+
];
12+
13+
@NgModule({
14+
imports: [RouterModule.forChild(routes)],
15+
exports: [RouterModule],
16+
})
17+
export class Mensa2PageRoutingModule {}

src/app/pages/mensa2/mensa2.module.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { NgModule } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { FormsModule } from '@angular/forms';
4+
5+
import { IonicModule } from '@ionic/angular';
6+
7+
import { Mensa2PageRoutingModule } from './mensa2-routing.module';
8+
9+
import { Mensa2Page } from './mensa2.page';
10+
import { TranslateModule } from '@ngx-translate/core';
11+
import { ComponentsModule } from '../../components/components.module';
12+
13+
@NgModule({
14+
imports: [
15+
CommonModule,
16+
FormsModule,
17+
IonicModule,
18+
Mensa2PageRoutingModule,
19+
TranslateModule,
20+
ComponentsModule,
21+
],
22+
declarations: [Mensa2Page],
23+
})
24+
export class Mensa2PageModule {}

src/app/pages/mensa2/mensa2.page.html

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<ion-header>
2+
<ion-toolbar>
3+
<ion-back-button mode="md" slot="start"></ion-back-button>
4+
<ion-button
5+
mode="md"
6+
*ngIf="!(platform.is('ios') || platform.is('android'))"
7+
(click)="loadMenu(true)"
8+
slot="end"
9+
fill="clear"
10+
>
11+
<ion-icon style="font-size: x-large" name="refresh"></ion-icon>
12+
</ion-button>
13+
<ion-menu-button slot="end"></ion-menu-button>
14+
<ion-title>{{ "page.mensa2.title" | translate }}</ion-title>
15+
</ion-toolbar>
16+
<ion-toolbar *ngIf="isLoaded && !networkError">
17+
<ion-grid>
18+
<ion-row>
19+
<ion-col size="2">
20+
<app-date-picker
21+
[compactMode]="true"
22+
[inputDate]="selectedDate"
23+
(momentObjectEmitter)="pickDate($event)"
24+
></app-date-picker>
25+
</ion-col>
26+
<ion-col size="6">
27+
<ion-item class="mensaFilter" mode="md" lines="none">
28+
<ion-label>Filter</ion-label>
29+
<ion-select
30+
multiple="true"
31+
(ionChange)="filterMenus($event)"
32+
okText="{{ 'button.ok' | translate }}"
33+
cancelText="{{ 'button.cancel' | translate }}"
34+
[disabled]="filterKeywords.length === 0"
35+
>
36+
<ion-select-option *ngFor="let filter of filterKeywords"
37+
>{{ filter }}</ion-select-option
38+
>
39+
</ion-select>
40+
</ion-item>
41+
</ion-col>
42+
</ion-row>
43+
</ion-grid>
44+
</ion-toolbar>
45+
</ion-header>
46+
47+
<ion-content>
48+
<ion-refresher
49+
*ngIf="platform.is('ios') || platform.is('android')"
50+
slot="fixed"
51+
(ionRefresh)="loadMenu($event)"
52+
>
53+
<ion-refresher-content
54+
pullingIcon="refresh"
55+
refreshingSpinner="dots"
56+
></ion-refresher-content>
57+
</ion-refresher>
58+
</ion-content>

src/app/pages/mensa2/mensa2.page.scss

Whitespace-only changes.
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2+
import { IonicModule } from '@ionic/angular';
3+
4+
import { Mensa2Page } from './mensa2.page';
5+
6+
describe('Mensa2Page', () => {
7+
let component: Mensa2Page;
8+
let fixture: ComponentFixture<Mensa2Page>;
9+
10+
beforeEach(waitForAsync(() => {
11+
TestBed.configureTestingModule({
12+
declarations: [Mensa2Page],
13+
imports: [IonicModule.forRoot()],
14+
}).compileComponents();
15+
16+
fixture = TestBed.createComponent(Mensa2Page);
17+
component = fixture.componentInstance;
18+
fixture.detectChanges();
19+
}));
20+
21+
it('should create', () => {
22+
expect(component).toBeTruthy();
23+
});
24+
});

src/app/pages/mensa2/mensa2.page.ts

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { AbstractPage } from '../../lib/abstract-page';
3+
import { ICampus, IMeals, IMensaResponse } from '../../lib/interfaces';
4+
import { default as moment } from 'moment/moment';
5+
import { convertToArray, isInArray } from '../../lib/util';
6+
import jquery from 'jquery';
7+
import { IMensaRequestParams } from '../../services/webservice-wrapper/webservice-definition-interfaces';
8+
import { TranslateService } from '@ngx-translate/core';
9+
import { WebserviceWrapperService } from '../../services/webservice-wrapper/webservice-wrapper.service';
10+
11+
@Component({
12+
selector: 'app-mensa2',
13+
templateUrl: './mensa2.page.html',
14+
styleUrls: ['./mensa2.page.scss'],
15+
})
16+
export class Mensa2Page extends AbstractPage implements OnInit {
17+
isLoaded;
18+
networkError;
19+
selectedDate;
20+
currentDate = moment();
21+
filterKeywords = [];
22+
23+
ulfMeals: IMeals[] = [];
24+
displayedUlfMeals: IMeals[] = [];
25+
ulfMealForDate: boolean[] = [];
26+
ulfIconMapping = [];
27+
noUlfMealsForDate;
28+
campus: ICampus;
29+
30+
constructor(
31+
private translate: TranslateService,
32+
private ws: WebserviceWrapperService
33+
) {
34+
super({ optionalNetwork: true });
35+
}
36+
37+
ngOnInit() {}
38+
39+
loadMenu(refresher?) {
40+
if (!(refresher && refresher.target)) {
41+
this.isLoaded = false;
42+
}
43+
44+
this.ulfMeals = undefined;
45+
this.displayedUlfMeals = undefined;
46+
for (let i = 0; i < this.ulfMealForDate.length; i++) {
47+
this.ulfMealForDate[i] = false;
48+
}
49+
50+
this.noUlfMealsForDate = true;
51+
this.networkError = false;
52+
53+
this.ws
54+
.call(
55+
'mensa',
56+
{
57+
campus_canteen_name: this.campus.canteen_name,
58+
} as IMensaRequestParams,
59+
{ forceRefreshGroup: refresher !== undefined }
60+
)
61+
.subscribe(
62+
(res: IMensaResponse) => {
63+
res.meal = res.meal.sort((a, b) => {
64+
if (a.title === 'Info') {
65+
return -1;
66+
} else {
67+
return 0;
68+
}
69+
});
70+
71+
if (this.campus.canteen_name === 'Griebnitzsee') {
72+
const ulfParam = 'UlfsCafe';
73+
this.ws
74+
.call('mensa', {
75+
campus_canteen_name: ulfParam,
76+
} as IMensaRequestParams)
77+
.subscribe((resUlf: IMensaResponse) => {
78+
if (resUlf.meal) {
79+
this.ulfMeals = resUlf.meal;
80+
this.displayedUlfMeals = resUlf.meal;
81+
}
82+
if (resUlf.iconHashMap && resUlf.iconHashMap.entry) {
83+
this.ulfIconMapping = resUlf.iconHashMap.entry;
84+
}
85+
if (refresher && refresher.target) {
86+
refresher.target.complete();
87+
}
88+
});
89+
}
90+
},
91+
() => {
92+
this.isLoaded = true;
93+
this.networkError = true;
94+
if (refresher && refresher.target) {
95+
refresher.target.complete();
96+
}
97+
}
98+
);
99+
}
100+
101+
pickDate($event) {
102+
this.selectedDate = $event;
103+
this.noUlfMealsForDate = true;
104+
105+
let i;
106+
let mealDate;
107+
108+
if (this.displayedUlfMeals) {
109+
for (i = 0; i < this.displayedUlfMeals.length; i++) {
110+
if (this.displayedUlfMeals[i].date) {
111+
mealDate = moment(this.displayedUlfMeals[i].date);
112+
} else {
113+
mealDate = moment();
114+
}
115+
116+
if ($event.format('MM DD YYYY') === mealDate.format('MM DD YYYY')) {
117+
this.ulfMealForDate[i] = true;
118+
this.noUlfMealsForDate = false;
119+
} else {
120+
this.ulfMealForDate[i] = false;
121+
}
122+
}
123+
}
124+
}
125+
126+
filterMenus(event) {
127+
const filter = convertToArray(event.detail.value);
128+
129+
this.displayedUlfMeals = this.ulfMeals;
130+
131+
if (filter && filter.length > 0) {
132+
if (this.displayedUlfMeals) {
133+
this.displayedUlfMeals = jquery.grep(this.displayedUlfMeals, (meal) => {
134+
if (meal.type) {
135+
let fulfillsConditions = false;
136+
for (const flt of filter) {
137+
if (isInArray(meal.type, flt)) {
138+
fulfillsConditions = true;
139+
break;
140+
}
141+
}
142+
return fulfillsConditions;
143+
} else {
144+
return false;
145+
}
146+
});
147+
}
148+
}
149+
150+
this.classifyMeals();
151+
}
152+
153+
classifyMeals() {
154+
let mealDate;
155+
156+
if (this.displayedUlfMeals) {
157+
for (let i = 0; i < this.displayedUlfMeals.length; i++) {
158+
if (this.displayedUlfMeals[i].date) {
159+
mealDate = moment(this.displayedUlfMeals[i].date);
160+
} else {
161+
mealDate = moment();
162+
}
163+
164+
if (
165+
this.currentDate.format('MM DD YYYY') ===
166+
mealDate.format('MM DD YYYY')
167+
) {
168+
this.ulfMealForDate[i] = true;
169+
this.noUlfMealsForDate = false;
170+
} else {
171+
this.ulfMealForDate[i] = false;
172+
}
173+
}
174+
}
175+
176+
this.isLoaded = true;
177+
this.pickDate(this.selectedDate);
178+
}
179+
}

src/assets/config.dist.json

+5
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@
8686
"icon": "restaurant",
8787
"selected": true
8888
},
89+
"mensa2": {
90+
"componentName": "mensa2",
91+
"icon": "restaurant",
92+
"selected": true
93+
},
8994
"moodle": {
9095
"componentName": "moodle",
9196
"customIcon": "./assets/icon/moodle.svg",

src/assets/i18n/de.json

+3
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,9 @@
316316
"mensaClosed": "Diese Mensa ist derzeit geschlossen.",
317317
"foodhopperGriebnitzsee": "Der Food Hopper in der Stahnsdorfer Str. 140-156 ist geöffnet und bietet warmes Mittagessen zum Mitnehmen an."
318318
},
319+
"mensa2": {
320+
"title": "Mensa2"
321+
},
319322
"unishop": {
320323
"title": "UNIshop"
321324
},

0 commit comments

Comments
 (0)