finished schedule page + added substitution functions
This commit is contained in:
@@ -12,6 +12,27 @@ export class IServService {
|
||||
public keys?: AuthKeys;
|
||||
public backend: string = "http://localhost:5273";
|
||||
|
||||
public courseNames: {[id: string]: string} = {
|
||||
["Bi"]: "Biologie",
|
||||
["Ch"]: "Chemie",
|
||||
["Ma"]: "Mathe",
|
||||
["Ph"]: "Physik",
|
||||
["De"]: "Deutsch",
|
||||
["Ek"]: "Erdkunde",
|
||||
["En"]: "Englisch",
|
||||
["PW"]: "Politik",
|
||||
["Sn"]: "Spanisch",
|
||||
["If"]: "Informatik",
|
||||
["Sp"]: "Sport",
|
||||
["WN"]: "Werte und Normen",
|
||||
["La"]: "Latein",
|
||||
["Re"]: "Religion",
|
||||
["Ge"]: "Geschichte",
|
||||
["Ku"]: "Kunst",
|
||||
["Sf"]: "Seminarfach",
|
||||
["DS"]: "Darstellendes Spiel",
|
||||
};
|
||||
|
||||
constructor(private client: HttpClient) {
|
||||
const data = localStorage.getItem("userdata");
|
||||
if (data != null) {
|
||||
@@ -42,6 +63,11 @@ export class IServService {
|
||||
}
|
||||
}
|
||||
|
||||
public logout() {
|
||||
delete this.userdata;
|
||||
delete this.keys;
|
||||
}
|
||||
|
||||
public async getKeys(): Promise<AuthKeys> {
|
||||
const keys = await firstValueFrom(this.client.post<AuthKeys>(this.backend + "/iserv/login", this.userdata));
|
||||
localStorage.setItem("keys", JSON.stringify(keys));
|
||||
@@ -52,9 +78,34 @@ export class IServService {
|
||||
try {
|
||||
return (await firstValueFrom(this.client.post<{value: string[]}>(this.backend + "/iserv/groups?domain=" + this.userdata.domain, this.keys))).value;
|
||||
} catch {
|
||||
await this.getKeys();
|
||||
return (await firstValueFrom(this.client.post<{value: string[]}>(this.backend + "/iserv/groups?domain=" + this.userdata.domain, this.keys))).value;
|
||||
const keys = await this.getKeys();
|
||||
return (await firstValueFrom(this.client.post<{value: string[]}>(this.backend + "/iserv/groups?domain=" + this.userdata.domain, keys))).value;
|
||||
}
|
||||
}
|
||||
|
||||
public async getCoursesAndClass(groups?: string[]): Promise<{class: string, courses: string[]}> {
|
||||
if (groups == undefined) {
|
||||
groups = await this.getGroups();
|
||||
}
|
||||
|
||||
const result: {class: string, courses: string[]} = {class: undefined, courses: []};
|
||||
|
||||
const classNames = groups.filter(group => group.startsWith("Klasse ") && !group.includes("."));
|
||||
if (classNames.length != 0) {
|
||||
result.class = classNames[0].replace("Klasse ", "");
|
||||
}else {
|
||||
const grades = groups.filter(group => group.startsWith("Jahrgang ") && !group.includes("."));
|
||||
if (grades.length != 0) {
|
||||
result.class = grades[0].replace("Jahrgang ", "").toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
for (let group of groups) {
|
||||
if (!group.includes(".") || !group.toLowerCase().startsWith("q")) continue;
|
||||
result.courses.push(group.split(".")[1]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<ion-app>
|
||||
<ion-split-pane contentId="main-content">
|
||||
<ion-menu contentId="main-content" type="overlay" *ngIf="router.url != '/login'">
|
||||
<ion-menu contentId="main-content" type="overlay" [ngClass]="{'hide': router.url == '/login'}">
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-list-header>BetterIServ</ion-list-header>
|
||||
|
||||
@@ -107,3 +107,7 @@ ion-note {
|
||||
ion-item.selected {
|
||||
--color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ export class AppComponent {
|
||||
}
|
||||
|
||||
public logout() {
|
||||
localStorage.removeItem("userdata");
|
||||
localStorage.clear();
|
||||
this.iserv.logout();
|
||||
this.router.navigate(["login"]);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,4 +26,12 @@ export const routes: Routes = [
|
||||
path: 'substitution',
|
||||
loadComponent: () => import('./pages/substitution/substitution.page').then( m => m.SubstitutionPage)
|
||||
},
|
||||
{
|
||||
path: 'tasks',
|
||||
loadComponent: () => import('./pages/tasks/tasks.page').then( m => m.TasksPage)
|
||||
},
|
||||
{
|
||||
path: 'schedule',
|
||||
loadComponent: () => import('./pages/schedule/schedule.page').then( m => m.SchedulePage)
|
||||
},
|
||||
];
|
||||
|
||||
16
BetterIServ.Mobile/src/app/entities/course.ts
Normal file
16
BetterIServ.Mobile/src/app/entities/course.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export interface Course {
|
||||
id: string;
|
||||
name: string;
|
||||
short: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export type Lesson = {course: string, room: string, week?: 'a' | 'b' | 'all'};
|
||||
|
||||
export interface Timetable {
|
||||
mon: Lesson[];
|
||||
tue: Lesson[];
|
||||
wed: Lesson[];
|
||||
thu: Lesson[];
|
||||
fri: Lesson[];
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
ion-card {
|
||||
width: 90%;
|
||||
max-width: 700px;
|
||||
|
||||
ion-card-content {
|
||||
display: flex;
|
||||
|
||||
185
BetterIServ.Mobile/src/app/pages/schedule/schedule.page.html
Normal file
185
BetterIServ.Mobile/src/app/pages/schedule/schedule.page.html
Normal file
@@ -0,0 +1,185 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Stundenplan</ion-title>
|
||||
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="onEditOrAdd()"><ion-icon ios="add-circle-outline" md="add-circle-sharp"></ion-icon></ion-button>
|
||||
|
||||
<ion-modal #courseModal (willDismiss)="updateOrCreateCourse($event)">
|
||||
<ng-template>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button (click)="courseModal.dismiss(null, 'cancel')">Abbrechen</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-title>{{currentCourse?.name || "Neuer Kurs"}}</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="courseModal.dismiss({id: id.value, short: short.value, name: name.value, color: color.value}, 'confirm')" [strong]="true">Fertig</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding course-content">
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Farbe</ion-label>
|
||||
<ion-select aria-label="Farbe" interface="action-sheet" [value]="colors[0].val" #color>
|
||||
<ion-select-option *ngFor="let color of colors" [value]="color.val">
|
||||
{{color.name}}
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Name</ion-label>
|
||||
<ion-input aria-label="Name" type="text" [value]="currentCourse?.name" #name/>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Kürzel</ion-label>
|
||||
<ion-input aria-label="Kürzel" type="text" [value]="currentCourse?.short" #short/>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Identifikator</ion-label>
|
||||
<ion-input aria-label="Identifikator" type="text" [value]="currentCourse?.id" #id/>
|
||||
</ion-item>
|
||||
|
||||
<ion-button *ngIf="currentCourse != undefined" (click)="courseModal.dismiss(null, 'delete')" color="danger">Kurs löschen</ion-button>
|
||||
</ion-content>
|
||||
</ng-template>
|
||||
</ion-modal>
|
||||
<ion-modal #tableModal (didDismiss)="updateOrCreateLesson($event)">
|
||||
<ng-template>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button (click)="tableModal.dismiss(null, 'cancel')">Abbrechen</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-title>{{currentLesson?.lesson.course || "Neue Stunde"}}</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="tableModal.dismiss({lesson: {course: course.value, room: room.value, week: week.value}, day: day.value, time: lesson.value}, 'confirm')" [strong]="true">Fertig</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding course-content">
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Kurs</ion-label>
|
||||
<ion-select aria-label="Kurs" interface="action-sheet" [value]="currentLesson?.lesson.course || courses[0].id" #course>
|
||||
<ion-select-option *ngFor="let course of courses" [value]="course.id">
|
||||
{{course.name}}
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Wochentyp</ion-label>
|
||||
<ion-select aria-label="Wochentyp" interface="action-sheet" [value]="currentLesson?.lesson.week || 'all'" #week>
|
||||
<ion-select-option value="all">Immer</ion-select-option>
|
||||
<ion-select-option value="a">Woche A</ion-select-option>
|
||||
<ion-select-option value="b">Woche B</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Raum</ion-label>
|
||||
<ion-input aria-label="Raum" type="text" [value]="currentLesson?.lesson.room" #room/>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Wochentag</ion-label>
|
||||
<ion-select aria-label="Wochentag" interface="action-sheet" [value]="currentLesson?.day || 'mon'" #day>
|
||||
<ion-select-option *ngFor="let dayName of ['mon', 'tue', 'wed', 'thu', 'fri']" [value]="dayName">
|
||||
<ion-label *ngIf="dayName == 'mon'">Montag</ion-label>
|
||||
<ion-label *ngIf="dayName == 'tue'">Dinstag</ion-label>
|
||||
<ion-label *ngIf="dayName == 'wed'">Mittwoch</ion-label>
|
||||
<ion-label *ngIf="dayName == 'thu'">Donnerstag</ion-label>
|
||||
<ion-label *ngIf="dayName == 'fri'">Freitag</ion-label>
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stunde</ion-label>
|
||||
<ion-select aria-label="Stunde" interface="action-sheet" [value]="currentLesson?.time || 0" #lesson>
|
||||
<ion-select-option *ngFor="let lessonName of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" [value]="lessonName">
|
||||
{{lessonName + 1}}
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-button *ngIf="currentLesson != undefined" color="danger" (click)="tableModal.dismiss(null, 'delete')">Stunde löschen</ion-button>
|
||||
</ion-content>
|
||||
</ng-template>
|
||||
</ion-modal>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">Stundenplan</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<section class="courses" *ngIf="showCourses">
|
||||
<ion-item><ion-label>Meine Kurse</ion-label></ion-item>
|
||||
<div class="course-container">
|
||||
<ion-card *ngFor="let course of courses" (click)="onEditOrAdd(course)">
|
||||
<ion-card-header>
|
||||
<span
|
||||
class="icon ion-text-center"
|
||||
[style]="'--background: var(--ion-color-' + course.color + '); --foreground: var(--ion-color-' + course.color + '-contrast)'"
|
||||
>
|
||||
{{course.short}}
|
||||
</span>
|
||||
</ion-card-header>
|
||||
<ion-card-content class="ion-text-center">
|
||||
<ion-label>{{course.name}}</ion-label><br>
|
||||
<ion-label>{{course.id}}</ion-label>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="timetable" *ngIf="!showCourses">
|
||||
<div *ngFor="let day of ['mon', 'tue', 'wed', 'thu', 'fri']" class="ion-text-center">
|
||||
<ion-label *ngIf="day == 'mon'">Mo</ion-label>
|
||||
<ion-label *ngIf="day == 'tue'">Di</ion-label>
|
||||
<ion-label *ngIf="day == 'wed'">Mi</ion-label>
|
||||
<ion-label *ngIf="day == 'thu'">Do</ion-label>
|
||||
<ion-label *ngIf="day == 'fri'">Fr</ion-label>
|
||||
|
||||
<ion-card *ngFor="let lesson of timetable[day] | week; let i = index" [ngClass]="{'hide': lesson == undefined}" (click)="onEditOrAdd(undefined, {lesson, day, time: i})">
|
||||
<ion-card-header>
|
||||
<span
|
||||
class="icon ion-text-center"
|
||||
[style]="'--background: var(--ion-color-' + findCourse(lesson?.course)?.color + '); --foreground: var(--ion-color-' + findCourse(lesson?.course)?.color + '-contrast)'"
|
||||
>
|
||||
{{findCourse(lesson?.course)?.short || "⠀ ⠀"}}
|
||||
</span>
|
||||
</ion-card-header>
|
||||
<ion-card-content class="ion-text-center">
|
||||
<ion-label>{{lesson?.room || "⠀ ⠀"}}</ion-label>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
</section>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-tab-button (click)="showCourses = false" [ngClass]="{'active': !showCourses}">
|
||||
<ion-icon ios="grid-outline" md="grid-sharp" />
|
||||
Stundenplan
|
||||
</ion-tab-button>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
<ion-tab-button (click)="showCourses = true" [ngClass]="{'active': showCourses}">
|
||||
<ion-icon ios="list-outline" md="list-sharp" />
|
||||
Kurse
|
||||
</ion-tab-button>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
64
BetterIServ.Mobile/src/app/pages/schedule/schedule.page.scss
Normal file
64
BetterIServ.Mobile/src/app/pages/schedule/schedule.page.scss
Normal file
@@ -0,0 +1,64 @@
|
||||
.course-content ion-item {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
|
||||
.icon {
|
||||
margin-inline: auto;
|
||||
aspect-ratio: 1;
|
||||
width: max-content;
|
||||
padding: 10px;
|
||||
border-radius: 50%;
|
||||
line-height: 20px;
|
||||
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.courses {
|
||||
ion-item {
|
||||
--background: transparent;
|
||||
--border-color: transparent;
|
||||
}
|
||||
|
||||
.course-container {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
margin: 16px;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
|
||||
ion-card {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ion-item {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.timetable {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
gap: 5px;
|
||||
padding-inline: 16px;
|
||||
|
||||
div {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
padding-block: 16px;
|
||||
}
|
||||
|
||||
ion-card {
|
||||
margin: 10px 0 0;
|
||||
width: 100%;
|
||||
|
||||
ion-card-header, ion-card-content {
|
||||
padding: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hide {
|
||||
opacity: 0;
|
||||
}
|
||||
129
BetterIServ.Mobile/src/app/pages/schedule/schedule.page.ts
Normal file
129
BetterIServ.Mobile/src/app/pages/schedule/schedule.page.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import {Component, ElementRef, NgZone, OnInit, ViewChild} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import {IonicModule, IonModal} from '@ionic/angular';
|
||||
import {IServService} from "../../api/iserv.service";
|
||||
import {Course, Lesson, Timetable} from "../../entities/course";
|
||||
import {WeekPipe} from "../../pipes/week.pipe";
|
||||
|
||||
@Component({
|
||||
selector: 'app-schedule',
|
||||
templateUrl: './schedule.page.html',
|
||||
styleUrls: ['./schedule.page.scss'],
|
||||
standalone: true,
|
||||
imports: [IonicModule, CommonModule, FormsModule, WeekPipe]
|
||||
})
|
||||
export class SchedulePage implements OnInit {
|
||||
|
||||
public showCourses: boolean = false;
|
||||
public courses: Course[] = [];
|
||||
public currentCourse: Course;
|
||||
public timetable: Timetable = {mon: [], tue: [], wed: [], thu: [], fri: []};
|
||||
public currentLesson: {lesson: Lesson, day: string, time: number};
|
||||
public rerender: boolean = false;
|
||||
public colors: {name: string; val: string}[] = [
|
||||
{name: "Blau", val: "primary"},
|
||||
{name: "Hellblau", val: "secondary"},
|
||||
{name: "Lila", val: "tertiary"},
|
||||
{name: "Grün", val: "success"},
|
||||
{name: "Gelb", val: "warning"},
|
||||
{name: "Rot", val: "danger"}
|
||||
];
|
||||
|
||||
@ViewChild('courseModal') courseModal: IonModal;
|
||||
@ViewChild('tableModal') tableModal: IonModal;
|
||||
|
||||
constructor(private iserv: IServService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
if (localStorage.getItem("courses") == undefined) {
|
||||
const data = await this.iserv.getCoursesAndClass();
|
||||
|
||||
if (data.class.startsWith("Q")) {
|
||||
for (let course of data.courses) {
|
||||
const short = course.substring(1, 3);
|
||||
const name = this.iserv.courseNames[short];
|
||||
if (name == undefined) continue;
|
||||
this.courses.push({
|
||||
id: course,
|
||||
short: short.toUpperCase(),
|
||||
name: name,
|
||||
color: this.colors[Math.floor(Math.random() * this.colors.length)].val
|
||||
});
|
||||
}
|
||||
this.courses.sort((a, b) => {
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
localStorage.setItem("courses", JSON.stringify(this.courses));
|
||||
}
|
||||
}else {
|
||||
this.courses = JSON.parse(localStorage.getItem("courses"));
|
||||
}
|
||||
|
||||
if (localStorage.getItem("timetable") == undefined) {
|
||||
for (let day of ['mon', 'tue', 'wed', 'thu', 'fri']) {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
this.timetable[day].push(undefined);
|
||||
}
|
||||
}
|
||||
localStorage.setItem("timetable", JSON.stringify(this.timetable));
|
||||
}else {
|
||||
this.timetable = JSON.parse(localStorage.getItem("timetable"));
|
||||
}
|
||||
}
|
||||
|
||||
public async onEditOrAdd(course?: Course, lesson?: {lesson: Lesson, day: string, time: number}) {
|
||||
this.currentCourse = course;
|
||||
this.currentLesson = lesson;
|
||||
if (this.showCourses) await this.courseModal.present();
|
||||
else await this.tableModal.present();
|
||||
}
|
||||
|
||||
public async updateOrCreateCourse(event: any) {
|
||||
if (event.detail.role == "delete") {
|
||||
this.courses.splice(this.courses.indexOf(this.currentCourse), 1);
|
||||
}
|
||||
|
||||
if (event.detail.role == "confirm") {
|
||||
const data = event.detail.data as Course;
|
||||
|
||||
if (this.currentCourse != undefined) {
|
||||
this.courses[this.courses.indexOf(this.currentCourse)] = data;
|
||||
delete this.currentCourse;
|
||||
}else {
|
||||
this.courses.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
this.courses.sort((a, b) => {
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
localStorage.setItem("courses", JSON.stringify(this.courses));
|
||||
}
|
||||
|
||||
public async updateOrCreateLesson(event: any) {
|
||||
if (event.detail.role == "delete") {
|
||||
delete this.timetable[this.currentLesson.day][this.currentLesson.time];
|
||||
}
|
||||
|
||||
if (event.detail.role == "confirm") {
|
||||
const data = event.detail.data as {lesson: Lesson, day: string, time: number};
|
||||
this.timetable[data.day][data.time] = data.lesson;
|
||||
}
|
||||
|
||||
localStorage.setItem("timetable", JSON.stringify(this.timetable));
|
||||
location.reload();
|
||||
}
|
||||
|
||||
public findCourse(id: string): Course {
|
||||
for (let course of this.courses)
|
||||
if (course.id == id) return course;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: end;
|
||||
align-items: flex-end;
|
||||
|
||||
.type {
|
||||
font-size: 18px;
|
||||
|
||||
@@ -5,6 +5,7 @@ import {AlertController, IonicModule} from '@ionic/angular';
|
||||
import {UnitsService} from "../../api/units.service";
|
||||
import {Substitution, UnitsData} from "../../entities/substitution";
|
||||
import {IServService} from "../../api/iserv.service";
|
||||
import {Course} from "../../entities/course";
|
||||
|
||||
@Component({
|
||||
selector: 'app-substitution',
|
||||
@@ -40,10 +41,31 @@ export class SubstitutionPage implements OnInit {
|
||||
|
||||
this.data = await this.units.getSubstitutionPlan("today");
|
||||
|
||||
const groups = await this.iserv.getGroups();
|
||||
for (let group of groups) {
|
||||
if (!group.includes(".")) continue;
|
||||
this.courses.push(group.split(".")[1]);
|
||||
const data = await this.iserv.getCoursesAndClass();
|
||||
if (localStorage.getItem("class") == null) {
|
||||
if (!data.class.startsWith("Q")) {
|
||||
this.changeClass(data.class);
|
||||
}else {
|
||||
this.changeClass(data.class);
|
||||
this.showOnlyCourses(true);
|
||||
this.filterByClasses = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.class.startsWith("Q")) {
|
||||
if (localStorage.getItem("courses") != undefined) {
|
||||
const courses = JSON.parse(localStorage.getItem("courses")) as Course[];
|
||||
for (let course of courses) {
|
||||
this.courses.push(course.id);
|
||||
}
|
||||
}else {
|
||||
const alert = await this.alerts.create({
|
||||
header: "Achtung",
|
||||
message: "Füge deine Kurse im Stundenplan hinzu um sie hier zu filtern!",
|
||||
buttons: ["Ok"]
|
||||
});
|
||||
await alert.present();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
38
BetterIServ.Mobile/src/app/pages/tasks/tasks.page.html
Normal file
38
BetterIServ.Mobile/src/app/pages/tasks/tasks.page.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Aufgaben</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">Aufgaben</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-label>Coming soon!</ion-label>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-tab-button>
|
||||
<ion-icon ios="list-outline" md="list-sharp" />
|
||||
Aktuelle Aufgaben
|
||||
</ion-tab-button>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
<ion-tab-button>
|
||||
<ion-icon ios="folder-outline" md="folder-sharp" />
|
||||
Vergangene Aufgaben
|
||||
</ion-tab-button>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
20
BetterIServ.Mobile/src/app/pages/tasks/tasks.page.ts
Normal file
20
BetterIServ.Mobile/src/app/pages/tasks/tasks.page.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tasks',
|
||||
templateUrl: './tasks.page.html',
|
||||
styleUrls: ['./tasks.page.scss'],
|
||||
standalone: true,
|
||||
imports: [IonicModule, CommonModule, FormsModule]
|
||||
})
|
||||
export class TasksPage implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
35
BetterIServ.Mobile/src/app/pipes/week.pipe.ts
Normal file
35
BetterIServ.Mobile/src/app/pipes/week.pipe.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import {Lesson} from "../entities/course";
|
||||
|
||||
@Pipe({
|
||||
name: 'week',
|
||||
standalone: true
|
||||
})
|
||||
export class WeekPipe implements PipeTransform {
|
||||
|
||||
transform(objects: Lesson[]): Lesson[] {
|
||||
const week = this.getWeek(new Date()) % 2;
|
||||
const label = week == 0 ? "a" : "b";
|
||||
const result = [];
|
||||
for (let lesson of objects) {
|
||||
if (lesson != undefined && (lesson.week == "all" || lesson.week == label))
|
||||
result.push(lesson);
|
||||
else result.push(undefined);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private getWeek(orig: Date): number {
|
||||
const date = new Date(orig.getTime());
|
||||
date.setHours(0, 0, 0, 0);
|
||||
// Thursday in current week decides the year.
|
||||
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
|
||||
// January 4 is always in week 1.
|
||||
const week1 = new Date(date.getFullYear(), 0, 4);
|
||||
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
|
||||
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000
|
||||
- 3 + (week1.getDay() + 6) % 7) / 7);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
Reference in New Issue
Block a user