diff --git a/.run/Debug.run.xml b/.run/Debug.run.xml new file mode 100644 index 0000000..8263edb --- /dev/null +++ b/.run/Debug.run.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/package.json b/package.json index 8015639..9fe3dda 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "tsw-timetable-frontend", "version": "0.0.1", - "author": "Ionic Framework", - "homepage": "https://ionicframework.com/", + "author": "Jim Martens", + "homepage": "https://2martens.de/", + "description": "Frontend for timetable application", "scripts": { "ng": "ng", "start": "ng serve", @@ -76,6 +77,5 @@ "ts-node": "^8.3.0", "typescript": "~5.0.2", "webpack-bundle-analyzer": "^4.9.0" - }, - "description": "An Ionic project" + } } diff --git a/src/app/app.component.html b/src/app/app.component.html index 8418139..a5d7a67 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,26 +1,36 @@ - + - - Inbox - hi@ionicframework.com + + Timetable + {{ username$ | async }} - - + + + + {{ p.title }} + + + + + {{ p.title }} - - + - - Labels - - - - {{ label }} + + + {{ p.title }} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index bf1443b..d2d632a 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,11 +1,13 @@ -import {CommonModule} from '@angular/common'; +import {AsyncPipe, NgFor, NgIf} from '@angular/common'; import {Component} from '@angular/core'; import {RouterLink, RouterLinkActive} from '@angular/router'; import { IonApp, IonContent, + IonHeader, IonIcon, IonItem, + IonItemDivider, IonLabel, IonList, IonListHeader, @@ -13,61 +15,74 @@ import { IonMenuToggle, IonNote, IonRouterOutlet, - IonSplitPane + IonSplitPane, + IonTitle, + IonToolbar } from '@ionic/angular/standalone'; import {addIcons} from 'ionicons'; import { - archiveOutline, - archiveSharp, - bookmarkOutline, - bookmarkSharp, - heartOutline, - heartSharp, - mailOutline, - mailSharp, - paperPlaneOutline, - paperPlaneSharp, - trashOutline, - trashSharp, - warningOutline, - warningSharp + homeOutline, + homeSharp, + logInOutline, + logInSharp, + logOutOutline, + logOutSharp, + readerOutline, + readerSharp, + shieldOutline, + shieldSharp } from 'ionicons/icons'; +import {KeycloakService} from "keycloak-angular"; +import {from, Observable, of, switchMap} from "rxjs"; @Component({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['app.component.scss'], standalone: true, - imports: [RouterLink, RouterLinkActive, CommonModule, IonApp, IonSplitPane, IonMenu, IonContent, IonList, - IonListHeader, IonNote, IonMenuToggle, IonItem, IonIcon, IonLabel, IonRouterOutlet], + imports: [RouterLink, RouterLinkActive, IonApp, IonSplitPane, IonMenu, IonContent, IonList, + IonListHeader, IonNote, IonMenuToggle, IonItem, IonIcon, IonLabel, IonRouterOutlet, NgIf, NgFor, AsyncPipe, IonItemDivider, IonHeader, IonToolbar, IonTitle], }) export class AppComponent { public appPages = [ - {title: 'Inbox', url: '/folder/inbox', icon: 'mail'}, - {title: 'Outbox', url: '/folder/outbox', icon: 'paper-plane'}, - {title: 'Favorites', url: '/folder/favorites', icon: 'heart'}, - {title: 'Archived', url: '/folder/archived', icon: 'archive'}, - {title: 'Trash', url: '/folder/trash', icon: 'trash'}, - {title: 'Spam', url: '/folder/spam', icon: 'warning'}, + {title: $localize`Dashboard`, url: '', icon: 'home'}, + {title: $localize`Privacy Policy`, url: '/privacy-policy', icon: 'shield'}, + {title: $localize`Legal Notice`, url: '/legal-notice', icon: 'reader'}, ]; - public labels = []; + public accountPages = [ + {title: $localize`Logout`, url: '/logout', icon: 'log-out'}, + ]; + public loggedOutPages = [ + {title: $localize`Logout`, url: '/login', icon: 'log-in'}, + ] + public isLoggedIn$: Observable; + public username$: Observable; - constructor() { + constructor( + private keycloakService: KeycloakService + ) { + this.isLoggedIn$ = from(this.keycloakService.isLoggedIn()); + this.username$ = this.isLoggedIn$.pipe( + switchMap(loggedIn => { + if (loggedIn) { + return of(this.keycloakService.getUsername()); + } else { + return of(''); + } + }) + ) addIcons({ - mailOutline, - mailSharp, - paperPlaneOutline, - paperPlaneSharp, - heartOutline, - heartSharp, - archiveOutline, - archiveSharp, - trashOutline, - trashSharp, - warningOutline, - warningSharp, - bookmarkOutline, - bookmarkSharp + homeOutline, + homeSharp, + logInOutline, + logInSharp, + logOutOutline, + logOutSharp, + shieldOutline, + shieldSharp, + readerOutline, + readerSharp, }); } + } diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 941c674..4947111 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,15 +1,11 @@ import {Routes} from '@angular/router'; +import {AppAuthGuard} from "./auth/auth.guard"; export const ROOT_ROUTES: Routes = [ - { - path: '', - loadComponent: () => import("./dashboard/dashboard.component").then(mod => mod.DashboardComponent), - pathMatch: 'full', - }, { path: 'permission-denied', loadComponent: () => import("./permission-denied/permission-denied.component") - .then(mod => mod.PermissionDeniedComponent) + .then(mod => mod.PermissionDeniedComponent), }, { path: 'legal-notice', @@ -19,4 +15,18 @@ export const ROOT_ROUTES: Routes = [ path: 'privacy-policy', loadComponent: () => import("./privacy-policy/privacy-policy.component").then(mod => mod.PrivacyPolicyComponent) }, + { + path: 'login', + loadComponent: () => import("./login/login.component").then(mod => mod.LoginComponent) + }, + { + path: 'logout', + loadComponent: () => import("./logout/logout.component").then(mod => mod.LogoutComponent), + canActivate: [AppAuthGuard] + }, + { + path: '', + loadComponent: () => import("./dashboard/dashboard.component").then(mod => mod.DashboardComponent), + pathMatch: 'full', + }, ]; diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index a1c4f82..d6f3014 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -1,5 +1,13 @@ import {Component} from '@angular/core'; -import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} from "@ionic/angular/standalone"; +import { + IonButtons, + IonContent, + IonHeader, + IonMenuButton, + IonMenuToggle, + IonTitle, + IonToolbar +} from "@ionic/angular/standalone"; @Component({ selector: 'app-dashboard', @@ -12,7 +20,8 @@ import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} IonMenuButton, IonTitle, IonToolbar, - IonContent + IonContent, + IonMenuToggle ] }) export class DashboardComponent { diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html new file mode 100644 index 0000000..b3c47ac --- /dev/null +++ b/src/app/login/login.component.html @@ -0,0 +1,22 @@ + + + + + + Timetable + + + + + + + Timetable + + + +
+

+ TODO +

+
+
diff --git a/src/app/login/login.component.scss b/src/app/login/login.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/login/login.component.spec.ts b/src/app/login/login.component.spec.ts new file mode 100644 index 0000000..54d2a77 --- /dev/null +++ b/src/app/login/login.component.spec.ts @@ -0,0 +1,24 @@ +import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; +import {IonicModule} from '@ionic/angular'; + +import {LoginComponent} from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [LoginComponent], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts new file mode 100644 index 0000000..93e0d57 --- /dev/null +++ b/src/app/login/login.component.ts @@ -0,0 +1,26 @@ +import {Component, OnInit} from '@angular/core'; +import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} from "@ionic/angular/standalone"; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.scss'], + imports: [ + IonButtons, + IonContent, + IonHeader, + IonMenuButton, + IonTitle, + IonToolbar + ], + standalone: true +}) +export class LoginComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/logout/logout.component.html b/src/app/logout/logout.component.html new file mode 100644 index 0000000..b3c47ac --- /dev/null +++ b/src/app/logout/logout.component.html @@ -0,0 +1,22 @@ + + + + + + Timetable + + + + + + + Timetable + + + +
+

+ TODO +

+
+
diff --git a/src/app/logout/logout.component.scss b/src/app/logout/logout.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/logout/logout.component.spec.ts b/src/app/logout/logout.component.spec.ts new file mode 100644 index 0000000..2891428 --- /dev/null +++ b/src/app/logout/logout.component.spec.ts @@ -0,0 +1,24 @@ +import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; +import {IonicModule} from '@ionic/angular'; + +import {LogoutComponent} from './logout.component'; + +describe('LogoutComponent', () => { + let component: LogoutComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [LogoutComponent], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(LogoutComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/logout/logout.component.ts b/src/app/logout/logout.component.ts new file mode 100644 index 0000000..2ef4412 --- /dev/null +++ b/src/app/logout/logout.component.ts @@ -0,0 +1,26 @@ +import {Component, OnInit} from '@angular/core'; +import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} from "@ionic/angular/standalone"; + +@Component({ + selector: 'app-logout', + templateUrl: './logout.component.html', + styleUrls: ['./logout.component.scss'], + imports: [ + IonButtons, + IonContent, + IonHeader, + IonMenuButton, + IonTitle, + IonToolbar + ], + standalone: true +}) +export class LogoutComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +}