From 72a79479a8cded0101ab1b3eb9875d521b41f7f6 Mon Sep 17 00:00:00 2001
From: Eduardo Lopes <155753879+eduardolopesx03@users.noreply.github.com>
Date: Thu, 22 Jan 2026 16:56:54 -0300
Subject: [PATCH] =?UTF-8?q?Refina=20layout=20dos=20cards=20de=20notifica?=
=?UTF-8?q?=C3=A7=C3=B5es?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/app/components/header/header.html | 31 +++++++++--
src/app/components/header/header.scss | 49 +++++++++++++++++
src/app/components/header/header.ts | 56 +++++++++++++++++++-
src/app/pages/notificacoes/notificacoes.html | 12 ++---
src/app/pages/notificacoes/notificacoes.scss | 28 ++++------
5 files changed, 145 insertions(+), 31 deletions(-)
diff --git a/src/app/components/header/header.html b/src/app/components/header/header.html
index de807c6..6eeb294 100644
--- a/src/app/components/header/header.html
+++ b/src/app/components/header/header.html
@@ -50,11 +50,17 @@
-
- {{ n.tipo === 'Vencido' ? 'Vencido' : 'A vencer' }}
-
-
{{ n.titulo }}
-
{{ n.mensagem }}
+
+
+ {{ n.tipo === 'Vencido' ? 'Vencido' : 'A vencer' }}
+
+ {{ n.linha || '-' }}
+
+
+
Linha: {{ n.linha || '-' }}
+
Cliente: {{ n.cliente || '-' }}
+
{{ n.tipo === 'Vencido' ? 'Venceu em' : 'Vence em' }}: {{ n.referenciaData ? (n.referenciaData | date:'dd/MM/yyyy') : '-' }}
+
@@ -117,6 +123,21 @@
+
+
+
+
+ A linha {{ toastItem.linha || '-' }} vence em 5 dias.
+
+
+
+
+
diff --git a/src/app/components/header/header.scss b/src/app/components/header/header.scss
index e9e85b8..70aa3da 100644
--- a/src/app/components/header/header.scss
+++ b/src/app/components/header/header.scss
@@ -242,6 +242,31 @@
background: rgba(3, 15, 170, 0.12);
}
+.notification-top {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+}
+
+.notification-line {
+ font-weight: 800;
+ font-size: 12px;
+ color: rgba(17, 18, 20, 0.65);
+}
+
+.notification-info {
+ margin-top: 8px;
+ display: grid;
+ gap: 4px;
+ font-size: 12px;
+ color: rgba(17, 18, 20, 0.75);
+
+ strong {
+ color: rgba(17, 18, 20, 0.9);
+ }
+}
+
.notification-tag.warn {
background: rgba(227, 61, 207, 0.16);
color: #8b2a7d;
@@ -282,6 +307,30 @@
}
}
+.notification-toast {
+ border-radius: 14px;
+ border: 1px solid rgba(0,0,0,0.08);
+ box-shadow: 0 18px 36px rgba(0,0,0,0.16);
+}
+
+.notification-toast .toast-header {
+ border-bottom: 1px solid rgba(0,0,0,0.06);
+ font-weight: 800;
+}
+
+.btn-aware {
+ display: inline-flex;
+ align-items: center;
+ margin-top: 10px;
+ padding: 6px 12px;
+ border-radius: 10px;
+ border: 1px solid rgba(0,0,0,0.1);
+ background: #fff;
+ font-size: 12px;
+ font-weight: 700;
+ cursor: pointer;
+}
+
.options-menu {
position: relative;
display: flex;
diff --git a/src/app/components/header/header.ts b/src/app/components/header/header.ts
index 78fca54..ed041d4 100644
--- a/src/app/components/header/header.ts
+++ b/src/app/components/header/header.ts
@@ -1,4 +1,4 @@
-import { Component, HostListener, Inject } from '@angular/core';
+import { Component, HostListener, Inject, ElementRef, ViewChild } from '@angular/core';
import { RouterLink, Router, NavigationEnd } from '@angular/router';
import { CommonModule, isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID } from '@angular/core';
@@ -24,6 +24,8 @@ export class Header {
notifications: NotificationDto[] = [];
notificationsLoading = false;
notificationsError = false;
+ private notificationsLoaded = false;
+ @ViewChild('notifToast') notifToast?: ElementRef;
private readonly loggedPrefixes = [
'/geral',
@@ -54,7 +56,13 @@ export class Header {
this.menuOpen = false;
this.optionsOpen = false;
this.notificationsOpen = false;
+ if (this.isLoggedHeader) {
+ this.ensureNotificationsLoaded();
+ }
});
+ if (this.isLoggedHeader) {
+ this.ensureNotificationsLoaded();
+ }
}
private syncHeaderState(rawUrl: string) {
@@ -137,6 +145,18 @@ export class Header {
this.closeNotifications();
}
+ acknowledgeNotification(notification: NotificationDto) {
+ if (!isPlatformBrowser(this.platformId)) return;
+ const acknowledged = this.getAcknowledgedIds();
+ acknowledged.add(notification.id);
+ localStorage.setItem('vigenciaAcknowledgedIds', JSON.stringify(Array.from(acknowledged)));
+ }
+
+ private ensureNotificationsLoaded() {
+ if (this.notificationsLoaded || this.notificationsLoading) return;
+ this.loadNotifications();
+ }
+
private loadNotifications() {
if (!isPlatformBrowser(this.platformId)) return;
this.notificationsLoading = true;
@@ -144,7 +164,9 @@ export class Header {
this.notificationsService.list().subscribe({
next: (data) => {
this.notifications = data || [];
+ this.notificationsLoaded = true;
this.notificationsLoading = false;
+ this.maybeShowVigenciaToast();
},
error: () => {
this.notificationsError = true;
@@ -152,4 +174,36 @@ export class Header {
},
});
}
+
+ private async maybeShowVigenciaToast() {
+ if (!this.notifToast || !isPlatformBrowser(this.platformId)) return;
+ const pending = this.getPendingVigenciaToast();
+ if (!pending) return;
+
+ const bs = await import('bootstrap');
+ const toast = new bs.Toast(this.notifToast.nativeElement, { autohide: false });
+ toast.show();
+ }
+
+ get toastNotification() {
+ return this.getPendingVigenciaToast();
+ }
+
+ private getPendingVigenciaToast() {
+ const acknowledged = this.getAcknowledgedIds();
+ return this.notifications.find(
+ n => n.tipo === 'AVencer' && n.diasParaVencer === 5 && !acknowledged.has(n.id)
+ );
+ }
+
+ private getAcknowledgedIds() {
+ if (!isPlatformBrowser(this.platformId)) return new Set
();
+ try {
+ const raw = localStorage.getItem('vigenciaAcknowledgedIds');
+ const ids = raw ? (JSON.parse(raw) as string[]) : [];
+ return new Set(ids);
+ } catch {
+ return new Set();
+ }
+ }
}
diff --git a/src/app/pages/notificacoes/notificacoes.html b/src/app/pages/notificacoes/notificacoes.html
index 9453576..9bddcb7 100644
--- a/src/app/pages/notificacoes/notificacoes.html
+++ b/src/app/pages/notificacoes/notificacoes.html
@@ -49,15 +49,13 @@
{{ n.tipo === 'Vencido' ? 'Vencido' : 'A vencer' }}
- {{ n.data | date:'dd/MM/yyyy' }}
+ {{ n.linha || '-' }}
-