intermediate commit

This commit is contained in:
Flo 2024-08-30 21:35:28 +00:00
parent 070e9bb876
commit 5facddcb5a
11 changed files with 164 additions and 19 deletions

View File

@ -1 +1,4 @@
<router-outlet></router-outlet> <router-outlet></router-outlet>
<div class="absolute bottom-0 w-full">
<app-notification-bar />
</div>

View File

@ -1,5 +1,7 @@
<app-navigation></app-navigation> <app-navigation></app-navigation>
<button (click)="fehler()">Fehler</button>
<div class="max-w-screen-xl mx-auto p-4"> <div class="max-w-screen-xl mx-auto p-4">
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>

View File

@ -1,8 +1,18 @@
import { Component } from "@angular/core"; import { Component } from "@angular/core";
import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: "app-home", selector: "app-home",
templateUrl: "./home.component.html", templateUrl: "./home.component.html",
styleUrls: ["./home.component.scss"], styleUrls: ["./home.component.scss"],
}) })
export class HomeComponent {} export class HomeComponent {
constructor(private notificationService: NotificationService) {}
fehler() {
this.notificationService.push({
message: "Ein Fehler ist aufgetreten :(",
type: "danger",
});
}
}

View File

@ -15,7 +15,7 @@
<!--User Bubble--> <!--User Bubble-->
<button <button
type="button" type="button"
class="block w-10 h-10 text-sm bg-skin-primary rounded-full md:me-0 focus:ring-4 focus:ring-skin-primary" class="w-10 h-10 text-sm bg-skin-primary rounded-full hidden md:block md:me-0 focus:ring-4 focus:ring-skin-primary"
id="user-menu-button" id="user-menu-button"
aria-expanded="false" aria-expanded="false"
data-dropdown-toggle="user-dropdown" data-dropdown-toggle="user-dropdown"
@ -68,6 +68,43 @@
</div> </div>
<ul class="p-4" aria-labelledby="user-menu-button"> <ul class="p-4" aria-labelledby="user-menu-button">
<li *ngFor="let usermenuButton of usermenuButtons">
<button
class="w-full text-left block py-2 px-3 rounded text-skin-primary hover:bg-skin-accent"
[routerLink]="
usermenuButton.routerLink === undefined
? null
: [usermenuButton.routerLink]
"
(click)="clickUserMenuButtonLabel(usermenuButton)"
>
{{ getUserMenuButtonLabel(usermenuButton) }}
</button>
</li>
</ul>
</div>
</div>
<!-- Navigation -->
<div
class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1"
id="navbar-user"
>
<div
class="text-base mt-4 list-none md:divide-y md:divide-skin-primary rounded-lg shadow-sm shadow-skin-primary md:hidden bg-skin-primary"
>
<div class="px-4 pt-3">
<span class="block text-sm text-skin-accent font-bold">{{
state?.username
}}</span>
<span class="block text-sm text-skin-primary-muted truncate">{{
state?.roleIdentifier
}}</span>
</div>
<ul
class="flex flex-col text-xl p-4 rounded-lg bg-skin-primary md:bg-skin-accent md:space-x-8"
>
<li *ngFor="let usermenuButton of usermenuButtons"> <li *ngFor="let usermenuButton of usermenuButtons">
<button <button
[routerLink]=" [routerLink]="
@ -83,13 +120,7 @@
</li> </li>
</ul> </ul>
</div> </div>
</div>
<!-- Navigatoin -->
<div
class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1"
id="navbar-user"
>
<ul <ul
class="flex flex-col text-xl p-4 md:p-0 mt-4 rounded-lg bg-skin-primary md:bg-skin-accent md:space-x-8 md:flex-row md:mt-0 md:border-0" class="flex flex-col text-xl p-4 md:p-0 mt-4 rounded-lg bg-skin-primary md:bg-skin-accent md:space-x-8 md:flex-row md:mt-0 md:border-0"
> >

View File

@ -0,0 +1,42 @@
<div
*ngFor="let element of elements"
class="flex items-center opacity-90 p-4 mb-4 text-skin-accent rounded-lg bg-skin-secondary md:max-w-3xl mx-5 md:mx-auto shadow-sm shadow-skin-primary"
>
<svg
class="flex-shrink-0 w-4 h-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"
/>
</svg>
<span class="sr-only">{{ element.type }}</span>
<div class="ms-3 text-sm font-medium">
{{ element.message }}
</div>
<button
type="button"
class="ms-auto -mx-1.5 -my-1.5 bg-skin-secondary text-skin-accent rounded-lg focus:ring-2 focus:ring-blue-400 p-1.5 hover:bg-skin-primary inline-flex items-center justify-center h-8 w-8"
(click)="dismiss(element)"
>
<span class="sr-only">Close</span>
<svg
class="w-3 h-3"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 14 14"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
/>
</svg>
</button>
</div>

View File

@ -0,0 +1,29 @@
import { Component } from "@angular/core";
import { NotificationService } from "../../services/notification.service";
import { filter } from "rxjs";
export interface NotificationElement {
message: string;
type: "info" | "danger" | "warn";
}
@Component({
selector: "app-notification-bar",
templateUrl: "./notification-bar.component.html",
styleUrls: ["./notification-bar.component.scss"],
})
export class NotificationBarComponent {
elements: NotificationElement[] = [];
constructor(private notificationService: NotificationService) {
this.notificationService.notification$.subscribe((notification) => {
if (notification !== undefined) {
this.elements.push(notification);
}
});
}
dismiss(element: NotificationElement): void {
this.elements = this.elements.filter((e) => e !== element);
}
}

View File

@ -11,6 +11,8 @@ import { TabProfileComponent } from "./components/settings/tabs/tab-profile/tab-
import { TabSecurityComponent } from "./components/settings/tabs/tab-security/tab-security.component"; import { TabSecurityComponent } from "./components/settings/tabs/tab-security/tab-security.component";
import { RouterModule } from "@angular/router"; import { RouterModule } from "@angular/router";
import { ReactiveFormsModule } from "@angular/forms"; import { ReactiveFormsModule } from "@angular/forms";
import { NotificationBarComponent } from "./components/notification-bar/notification-bar.component";
import { NotificationService } from "./services/notification.service";
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -18,14 +20,22 @@ import { ReactiveFormsModule } from "@angular/forms";
SettingsComponent, SettingsComponent,
TabProfileComponent, TabProfileComponent,
TabSecurityComponent, TabSecurityComponent,
NotificationBarComponent,
], ],
exports: [ exports: [
NavigationComponent, NavigationComponent,
SettingsComponent, SettingsComponent,
TabProfileComponent, TabProfileComponent,
TabSecurityComponent, TabSecurityComponent,
NotificationBarComponent,
], ],
imports: [CommonModule, SharedModule, RouterModule, ReactiveFormsModule], imports: [CommonModule, SharedModule, RouterModule, ReactiveFormsModule],
providers: [AuthGuard, AuthService, RequestService, AppService], providers: [
AuthGuard,
AuthService,
RequestService,
AppService,
NotificationService,
],
}) })
export class CoreModule {} export class CoreModule {}

View File

@ -0,0 +1,13 @@
import { Injectable } from "@angular/core";
import { BehaviorSubject, Observable, Subject } from "rxjs";
import { NotificationElement } from "../components/notification-bar/notification-bar.component";
@Injectable()
export class NotificationService {
notification$ = new Subject<NotificationElement>();
push(notification: NotificationElement): void {
console.log(notification.type + ": " + notification.message);
this.notification$.next(notification);
}
}

View File

@ -1,12 +1,17 @@
import { HttpClient } from "@angular/common/http"; import { HttpClient } from "@angular/common/http";
import { Router } from "@angular/router"; import { Router } from "@angular/router";
import { Injectable } from "@angular/core"; import { Injectable } from "@angular/core";
import { NotificationService } from "./notification.service";
@Injectable({ @Injectable({
providedIn: "root", providedIn: "root",
}) })
export class RequestService { export class RequestService {
constructor(private http: HttpClient, private router: Router) {} constructor(
private http: HttpClient,
private router: Router,
private notificationService: NotificationService
) {}
public post( public post(
apiPath: string, apiPath: string,
@ -86,7 +91,7 @@ export class RequestService {
} }
if (answer.status == 403) { if (answer.status == 403) {
this.showSnackBar("Du bist nicht für diese Aktion autorisiert", "Ok"); this.showSnackBar("Du bist nicht für diese Aktion autorisiert");
return; return;
} }
@ -101,14 +106,14 @@ export class RequestService {
throw errorObject.code.toString(); throw errorObject.code.toString();
} }
} catch (error: any) { } catch (error: any) {
this.showSnackBar(error.toString(), "Ok"); this.showSnackBar(error.toString());
} }
} }
private showSnackBar(message: string, action?: string) { private showSnackBar(message: string) {
/*this.snackBar.open(message.toString(), action, { this.notificationService.push({
duration: 3000, type: "info",
});*/ message: message,
console.log(message); });
} }
} }

View File

@ -8,8 +8,8 @@
--color-text-primary-muted: 100, 100, 100; --color-text-primary-muted: 100, 100, 100;
--color-text-secondary: 255, 255, 255; --color-text-secondary: 255, 255, 255;
--color-text-secondary-muted: 170, 170, 170; --color-text-secondary-muted: 170, 170, 170;
--color-text-accent: 255, 199, 44; --color-text-accent: 250, 183, 0;
--color-text-accent-muted: 255, 199, 44; --color-text-accent-muted: 250, 183, 0;
--color-primary: 244, 244, 245; --color-primary: 244, 244, 245;
--color-secondary: 238, 238, 240; --color-secondary: 238, 238, 240;