Aprimora UI das notificações e adiciona filtros

This commit is contained in:
Eduardo Lopes 2026-01-22 16:35:19 -03:00
parent cce651eef9
commit 8a12a2e0d0
4 changed files with 104 additions and 3 deletions

View File

@ -191,6 +191,7 @@
justify-content: space-between;
font-weight: 800;
color: rgba(17, 18, 20, 0.9);
border-bottom: 1px solid rgba(0,0,0,0.06);
}
.see-all {
@ -222,6 +223,12 @@
border-radius: 12px;
padding: 10px 12px;
margin-bottom: 10px;
transition: transform 0.2s ease, box-shadow 0.2s ease;
&:hover {
transform: translateY(-1px);
box-shadow: 0 10px 20px rgba(0,0,0,0.08);
}
}
.notification-tag {
@ -267,6 +274,12 @@
font-size: 12px;
font-weight: 700;
cursor: pointer;
color: rgba(17, 18, 20, 0.8);
&:hover {
border-color: rgba(3, 15, 170, 0.35);
color: #030faa;
}
}
.options-menu {

View File

@ -6,6 +6,32 @@
<h2>Notificações</h2>
<p>Acompanhe vencimentos e avisos recentes.</p>
</div>
<div class="filters">
<button
type="button"
class="filter-btn"
[class.active]="filter === 'todas'"
(click)="setFilter('todas')"
>
Todas
</button>
<button
type="button"
class="filter-btn warning"
[class.active]="filter === 'aVencer'"
(click)="setFilter('aVencer')"
>
A vencer
</button>
<button
type="button"
class="filter-btn danger"
[class.active]="filter === 'vencidas'"
(click)="setFilter('vencidas')"
>
Vencidas
</button>
</div>
</div>
<div class="state" *ngIf="loading">Carregando notificações...</div>
@ -13,9 +39,12 @@
<div class="state" *ngIf="!loading && !error && notifications.length === 0">
Nenhuma notificação encontrada.
</div>
<div class="state" *ngIf="!loading && !error && notifications.length > 0 && filteredNotifications.length === 0">
Nenhuma notificação para o filtro selecionado.
</div>
<div class="notifications-grid" *ngIf="!loading && !error && notifications.length > 0">
<article class="notification-card" *ngFor="let n of notifications">
<div class="notifications-grid" *ngIf="!loading && !error && filteredNotifications.length > 0">
<article class="notification-card" *ngFor="let n of filteredNotifications">
<div class="card-head">
<span class="tag" [class.danger]="n.tipo === 'Vencido'" [class.warn]="n.tipo === 'AVencer'">
{{ n.tipo === 'Vencido' ? 'Vencido' : 'A vencer' }}

View File

@ -19,9 +19,11 @@
.page-head {
display: flex;
align-items: flex-end;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
gap: 16px;
flex-wrap: wrap;
h2 {
font-size: 24px;
@ -36,6 +38,42 @@
}
}
.filters {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.filter-btn {
border: 1px solid rgba(0,0,0,0.08);
background: #fff;
padding: 8px 14px;
border-radius: 999px;
font-weight: 700;
font-size: 12px;
color: rgba(17, 18, 20, 0.7);
cursor: pointer;
transition: all 0.2s ease;
&.active {
border-color: rgba(3, 15, 170, 0.4);
background: rgba(3, 15, 170, 0.08);
color: #030faa;
}
&.warning.active {
border-color: rgba(227, 61, 207, 0.45);
background: rgba(227, 61, 207, 0.12);
color: #8b2a7d;
}
&.danger.active {
border-color: rgba(239, 68, 68, 0.45);
background: rgba(239, 68, 68, 0.12);
color: #b91c1c;
}
}
.state {
padding: 12px 14px;
border-radius: 12px;
@ -61,6 +99,12 @@
border: 1px solid rgba(0,0,0,0.08);
padding: 16px;
box-shadow: 0 18px 36px rgba(0,0,0,0.08);
transition: transform 0.2s ease, box-shadow 0.2s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 22px 44px rgba(0,0,0,0.12);
}
h3 {
margin: 12px 0 8px;

View File

@ -12,6 +12,7 @@ import { NotificationsService, NotificationDto } from '../../services/notificati
})
export class Notificacoes implements OnInit {
notifications: NotificationDto[] = [];
filter: 'todas' | 'vencidas' | 'aVencer' = 'todas';
loading = false;
error = false;
@ -31,6 +32,20 @@ export class Notificacoes implements OnInit {
});
}
setFilter(value: 'todas' | 'vencidas' | 'aVencer') {
this.filter = value;
}
get filteredNotifications() {
if (this.filter === 'vencidas') {
return this.notifications.filter(n => n.tipo === 'Vencido');
}
if (this.filter === 'aVencer') {
return this.notifications.filter(n => n.tipo === 'AVencer');
}
return this.notifications;
}
private loadNotifications() {
this.loading = true;
this.error = false;