();
+
+ subscribe(subscriberId: string, callback: NotificationCallback): void {
+ this.subscribers.set(
+ subscriberId,
+ this.bus.subscribe({
+ next: callback
+ })
+ );
+ }
+
+ publish(msg: string, type: NotificationType = NotificationType.Information) {
+ this.bus.next({ msg, type });
+ }
+
+ unsubscribe(subscriberId: string) {
+ this.subscribers.get(subscriberId)?.unsubscribe();
+ }
+}
diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html
index 9f4a656..bd828b2 100644
--- a/src/app/header/header.component.html
+++ b/src/app/header/header.component.html
@@ -9,4 +9,4 @@
login
Login
-
\ No newline at end of file
+
diff --git a/src/app/header/header.component.scss b/src/app/header/header.component.scss
index 4cb99ae..c9252ad 100644
--- a/src/app/header/header.component.scss
+++ b/src/app/header/header.component.scss
@@ -1,6 +1,4 @@
.header {
- position: sticky;
- top: 0;
margin: 0;
padding: 0.5rem 1rem;
z-index: 100;
@@ -31,3 +29,4 @@
min-width: fit-content;
}
}
+
diff --git a/src/app/notification-box/notification-box.component.html b/src/app/notification-box/notification-box.component.html
new file mode 100644
index 0000000..5dcc820
--- /dev/null
+++ b/src/app/notification-box/notification-box.component.html
@@ -0,0 +1,7 @@
+
+ @for (notification of notifications.values(); track notification){
+
+ {{notification.msg}}
+
+ }
+
diff --git a/src/app/notification-box/notification-box.component.scss b/src/app/notification-box/notification-box.component.scss
new file mode 100644
index 0000000..002d31e
--- /dev/null
+++ b/src/app/notification-box/notification-box.component.scss
@@ -0,0 +1,31 @@
+.notification-box {
+ position: absolute;
+ z-index: 100;
+ right: 0;
+ top: 3.5rem; // Header Height
+
+ width: 15%;
+ min-width: 20rem;
+
+ display: flex;
+ flex-direction: column;
+ padding: 0.5rem;
+ gap: 0.5rem;
+
+ overflow: hidden;
+
+ &__card {
+ width: 100%;
+ box-sizing: border-box;
+
+ &.info {
+ color: var(--mat-sys-tertiary);
+ background-color: var(--mat-sys-tertiary-container);
+ }
+
+ &.error {
+ color: var(--mat-sys-error);
+ background-color: var(--mat-sys-error-container);
+ }
+ }
+}
diff --git a/src/app/notification-box/notification-box.component.ts b/src/app/notification-box/notification-box.component.ts
new file mode 100644
index 0000000..693cc2b
--- /dev/null
+++ b/src/app/notification-box/notification-box.component.ts
@@ -0,0 +1,41 @@
+import { animate, style, transition, trigger } from '@angular/animations';
+import { Component, OnInit } from '@angular/core';
+import { MatCard, MatCardContent } from '@angular/material/card';
+import { Notification, NotificationService } from '@core/notification/notification.service';
+
+const NOTIFICATION_TTL = 3000;
+
+@Component({
+ selector: 'app-notification-box',
+ imports: [MatCard, MatCardContent],
+ animations: [
+ trigger('slideInOut', [
+ transition(':enter', [
+ style({ transform: 'translateX(100%)' }),
+ animate('200ms ease-in-out', style({ transform: 'translateX(0)' })),
+ ]),
+ transition(':leave', [animate('200ms ease-in-out', style({ transform: 'translateX(100%)' })),])
+ ]),
+ ],
+ templateUrl: './notification-box.component.html',
+ styleUrl: './notification-box.component.scss'
+})
+export class NotificationBoxComponent implements OnInit {
+ notifications: Map = new Map();
+
+ constructor(private notificationService: NotificationService) {
+ }
+
+ ngOnInit(): void {
+ this.notificationService.subscribe('notification-box', this.onNotification.bind(this));
+ }
+
+ onNotification(notification: Notification): void {
+ const now = Date.now();
+ this.notifications.set(now, notification);
+
+ setTimeout(() => {
+ this.notifications.delete(now);
+ }, NOTIFICATION_TTL);
+ }
+}
diff --git a/src/app/views/dashboard/dashboard.component.html b/src/app/views/dashboard/dashboard.component.html
index 9c5fce9..2e49c07 100644
--- a/src/app/views/dashboard/dashboard.component.html
+++ b/src/app/views/dashboard/dashboard.component.html
@@ -1 +1,4 @@
dashboard works!
+
+
+
diff --git a/src/app/views/dashboard/dashboard.component.ts b/src/app/views/dashboard/dashboard.component.ts
index 96e3d35..9455e38 100644
--- a/src/app/views/dashboard/dashboard.component.ts
+++ b/src/app/views/dashboard/dashboard.component.ts
@@ -1,11 +1,20 @@
import { Component } from '@angular/core';
+import { MatButton } from '@angular/material/button';
+
+import { NotificationService, NotificationType } from '../../core/notification/notification.service';
@Component({
selector: 'app-dashboard',
- imports: [],
+ imports: [MatButton],
templateUrl: './dashboard.component.html',
styleUrl: './dashboard.component.scss'
})
export class DashboardComponent {
+ constructor(private notifications: NotificationService) { }
+ testInfo() {
+ this.notifications.publish('Cake', NotificationType.Information);
+ }
-}
+ testError() {
+ this.notifications.publish('Cake', NotificationType.Error);
+ }}
diff --git a/src/styles.scss b/src/styles.scss
index 6cdd52a..e040c88 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -1,21 +1,21 @@
@use '@angular/material' as mat;
-html {
- color-scheme: light dark;
-
- @include mat.theme((color: mat.$azure-palette,
- typography: Roboto,
- density: 0));
- --mat-sys-primary-overlay: color-mix(in srgb, var(--mat-sys-primary) 10%, transparent);
-}
html,
body {
height: 100%;
-}
-
-body {
margin: 0;
+
background: var(--mat-sys-surface);
color: var(--mat-sys-on-surface);
+
+ --mat-sys-primary-overlay: color-mix(in srgb, var(--mat-sys-primary) 10%, transparent);
+
+ color-scheme: light dark;
+ font-family: var(--mat-sys-label-medium-font);
+
+ @include mat.theme((color: mat.$azure-palette,
+ typography: Roboto,
+ density: 0));
+
}