Reworked login system + added substitution page
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {Userdata} from "../entities/userdata";
|
||||
import {Userdata, AuthKeys} from "../entities/userdata";
|
||||
import {firstValueFrom} from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
@@ -20,17 +20,14 @@ export class IServService {
|
||||
|
||||
public async login(email: string, password: string): Promise<boolean> {
|
||||
const split = email.split('@');
|
||||
this.userdata = {};
|
||||
this.userdata.username = split[0];
|
||||
this.userdata.domain = split[1];
|
||||
this.userdata.password = password;
|
||||
|
||||
const data = new FormData();
|
||||
data.append("email", email);
|
||||
data.append("password", password);
|
||||
this.userdata = {
|
||||
username: split[0],
|
||||
domain: split[1],
|
||||
password
|
||||
};
|
||||
|
||||
try {
|
||||
this.userdata.token = await firstValueFrom(this.client.post(`${this.backend}/login`, data, {responseType: "text"}));
|
||||
await firstValueFrom(this.client.post(this.backend + "/auth/login", this.userdata));
|
||||
localStorage.setItem("userdata", JSON.stringify(this.userdata));
|
||||
return true;
|
||||
}catch (error) {
|
||||
@@ -38,4 +35,8 @@ export class IServService {
|
||||
}
|
||||
}
|
||||
|
||||
public async getKeys(): Promise<AuthKeys> {
|
||||
return await firstValueFrom(this.client.post<AuthKeys>(this.backend + "/auth/login", this.userdata));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ export class MailService {
|
||||
domain: this.iserv.userdata.domain,
|
||||
username: this.iserv.userdata.username,
|
||||
password: this.iserv.userdata.password,
|
||||
token: this.iserv.userdata.token,
|
||||
subject, receiver, mailBody
|
||||
};
|
||||
await firstValueFrom(this.client.post(this.iserv.backend + "/mail/send", data));
|
||||
|
||||
27
BetterIServ.Mobile/src/app/api/units.service.ts
Normal file
27
BetterIServ.Mobile/src/app/api/units.service.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {IServService} from "./iserv.service";
|
||||
import {UnitsData} from "../entities/substitution";
|
||||
import {firstValueFrom} from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UnitsService {
|
||||
|
||||
private schools: {[domain: string]: {today: string, tomorrow: string}} = {
|
||||
["hgbp.de"]: {
|
||||
today: "https://www.humboldt-gymnasium.de/vertretungsplan/PlanINet/heute/subst_001.htm",
|
||||
tomorrow: "https://www.humboldt-gymnasium.de/vertretungsplan/PlanINet/morgen/subst_001.htm"
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private iserv: IServService, private client: HttpClient) {}
|
||||
|
||||
public async getSubstitutionPlan(date: "today" | "tomorrow"): Promise<UnitsData> {
|
||||
if (this.schools[this.iserv.userdata.domain] == undefined) return undefined;
|
||||
const url = this.schools[this.iserv.userdata.domain][date];
|
||||
return await firstValueFrom(this.client.get<UnitsData>(this.iserv.backend + "/units/substitution?url=" + url));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,4 +22,8 @@ export const routes: Routes = [
|
||||
path: 'mails',
|
||||
loadComponent: () => import('./pages/mails/mails.page').then( m => m.MailsPage)
|
||||
},
|
||||
{
|
||||
path: 'substitution',
|
||||
loadComponent: () => import('./pages/substitution/substitution.page').then( m => m.SubstitutionPage)
|
||||
},
|
||||
];
|
||||
|
||||
15
BetterIServ.Mobile/src/app/entities/substitution.ts
Normal file
15
BetterIServ.Mobile/src/app/entities/substitution.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export interface Substitution {
|
||||
class: string;
|
||||
times: number[];
|
||||
type: string;
|
||||
representative: string;
|
||||
lesson: string;
|
||||
room: string;
|
||||
teacher: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface UnitsData {
|
||||
notifications: string[];
|
||||
substitutions: Substitution[];
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
export interface Userdata {
|
||||
domain?: string,
|
||||
username?: string,
|
||||
password?: string,
|
||||
token?: string
|
||||
domain: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface AuthKeys {
|
||||
session: string;
|
||||
sat: string;
|
||||
authSid: string;
|
||||
satId: string;
|
||||
authSession: string;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,3 @@ ion-label {
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ export class LoginPage implements OnInit {
|
||||
|
||||
await alert.present();
|
||||
}
|
||||
|
||||
console.log(this.iservApi.userdata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
ion-select {
|
||||
padding-inline: 15px;
|
||||
}
|
||||
|
||||
.mail > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
|
||||
<ion-segment value="today" (ionChange)="changeDate(segment.value)" #segment>
|
||||
<ion-segment-button value="today">
|
||||
<ion-label>Heute</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="tomorrow">
|
||||
<ion-label>Morgen</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">Vertretungsplan</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-select label="Klasse" [value]="currentClass" interface="action-sheet" (ionChange)="changeClass(select.value)" #select>
|
||||
<ion-select-option *ngFor="let className of getDistinctClasses()" [value]="className" [innerHtml]="className" />
|
||||
</ion-select>
|
||||
|
||||
<section *ngIf="showNews">
|
||||
<ion-card *ngFor="let info of data?.notifications">
|
||||
<ion-card-content>
|
||||
<ion-label [innerHtml]="info" style="color: #FFF"/>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</section>
|
||||
|
||||
<section *ngIf="!showNews">
|
||||
<ion-card
|
||||
*ngFor="let subs of data?.substitutions"
|
||||
class="subs {{subs.type.replace(' ', '')}}"
|
||||
[ngClass]="{'hide': subs.class != currentClass && currentClass != undefined}"
|
||||
>
|
||||
<ion-card-content>
|
||||
<ion-label class="times">{{subs.times.join(" - ")}}</ion-label>
|
||||
<div>
|
||||
<ion-label class="type">{{subs.type}}</ion-label>
|
||||
<ion-label class="desc" [innerHtml]="subs.lesson + ' (' + subs.teacher + ') ' + subs.room + ' ' + subs.description"></ion-label>
|
||||
</div>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</section>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-tab-button (click)="showNews = false" [ngClass]="{'active': !showNews}">
|
||||
<ion-icon ios="list-outline" md="list-sharp" />
|
||||
Vertretungen
|
||||
</ion-tab-button>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
<ion-tab-button (click)="showNews = true" [ngClass]="{'active': showNews}">
|
||||
<ion-icon ios="newspaper-outline" md="newspaper-sharp" />
|
||||
Nachrichten
|
||||
</ion-tab-button>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
@@ -0,0 +1,48 @@
|
||||
.subs {
|
||||
ion-card-content {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
color: #FFF;
|
||||
|
||||
.times {
|
||||
font-size: 25px;
|
||||
line-height: 25px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
div {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: end;
|
||||
|
||||
.type {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.Raumtausch {
|
||||
--background: var(--ion-color-success-shade);
|
||||
}
|
||||
|
||||
&.bittebeachten {
|
||||
--background: var(--ion-color-warning-shade);
|
||||
}
|
||||
|
||||
&.Vertretung {
|
||||
--background: var(--ion-color-primary-shade);
|
||||
}
|
||||
|
||||
&.Entfall, &.Stillarbeit {
|
||||
--background: var(--ion-color-danger-shade);
|
||||
}
|
||||
|
||||
&.Verlegung {
|
||||
--background: var(--ion-color-secondary-shade);
|
||||
}
|
||||
|
||||
&.hide {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import {UnitsService} from "../../api/units.service";
|
||||
import {UnitsData} from "../../entities/substitution";
|
||||
|
||||
@Component({
|
||||
selector: 'app-substitution',
|
||||
templateUrl: './substitution.page.html',
|
||||
styleUrls: ['./substitution.page.scss'],
|
||||
standalone: true,
|
||||
imports: [IonicModule, CommonModule, FormsModule]
|
||||
})
|
||||
export class SubstitutionPage implements OnInit {
|
||||
|
||||
public data: UnitsData;
|
||||
public showNews: boolean = false;
|
||||
public currentClass: string;
|
||||
|
||||
constructor(private units: UnitsService) {
|
||||
this.currentClass = localStorage.getItem("class");
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.data = await this.units.getSubstitutionPlan("today");
|
||||
}
|
||||
|
||||
public async changeDate(date: string) {
|
||||
this.data = await this.units.getSubstitutionPlan(date as "today" | "tomorrow");
|
||||
}
|
||||
|
||||
public getDistinctClasses(): string[] {
|
||||
const classes: string[] = [];
|
||||
if (this.data == undefined) return [];
|
||||
|
||||
for (let subs of this.data.substitutions) {
|
||||
if (classes.indexOf(subs.class) == -1) {
|
||||
classes.push(subs.class)
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
public changeClass(className: string) {
|
||||
this.currentClass = className;
|
||||
localStorage.setItem("class", className);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user