line-gestao-frontend/src/app/pages/notificacoes/notificacoes.html

210 lines
8.5 KiB
HTML

<section class="notificacoes-page">
<div class="wrap">
<div class="main-container">
<div class="page-header">
<div class="header-text">
<h2>Central de Notificações</h2>
<p>Gerencie seus alertas de vencimento e avisos do sistema.</p>
</div>
<div class="filters-bar">
<button type="button" class="pill" [class.active]="filter === 'todas'" (click)="setFilter('todas')">
Todas
</button>
<button type="button" class="pill" [class.active]="filter === 'aVencer'" (click)="setFilter('aVencer')">
A vencer
<span class="count-badge" *ngIf="countByType('AVencer') > 0">{{ countByType('AVencer') }}</span>
</button>
<button type="button" class="pill" [class.active]="filter === 'vencidas'" (click)="setFilter('vencidas')">
Vencidas
<span class="count-badge danger" *ngIf="countByType('Vencido') > 0">{{ countByType('Vencido') }}</span>
</button>
<button type="button" class="pill" [class.active]="filter === 'lidas'" (click)="setFilter('lidas')">
Arquivadas / Lidas
</button>
</div>
<div class="search-row" *ngIf="!loading && !error">
<div class="search-box">
<i class="bi bi-search"></i>
<input
type="text"
placeholder="Pesquisar..."
[(ngModel)]="search"
(ngModelChange)="clearSelection()"
/>
<button
type="button"
class="clear-btn"
*ngIf="search"
(click)="clearSearch()"
aria-label="Limpar busca"
>
<i class="bi bi-x-lg"></i>
</button>
</div>
</div>
<div class="bulk-actions-bar" *ngIf="!loading && !error">
<div class="bulk-left">
<label class="select-all" *ngIf="filteredNotifications.length > 0">
<input type="checkbox" [checked]="isAllSelected" (change)="toggleSelectAll()" />
<span>Selecionar todas</span>
</label>
<span class="bulk-count">
Mostrando {{ filteredNotifications.length }} notificações
<span class="bulk-selected" *ngIf="selectedIds.size > 0">• {{ selectedIds.size }} selecionada(s)</span>
</span>
</div>
<div class="bulk-actions" *ngIf="filter !== 'lidas'">
<button
type="button"
class="bulk-btn"
(click)="markAllAsRead()"
[disabled]="bulkLoading || filteredNotifications.length === 0"
>
<span *ngIf="!bulkLoading"><i class="bi bi-check2-all me-1"></i> Ler todas</span>
<span *ngIf="bulkLoading"><span class="spinner-border spinner-border-sm me-2"></span> Marcando...</span>
</button>
<button
type="button"
class="bulk-btn ghost"
(click)="exportNotifications()"
[disabled]="exportLoading || filteredNotifications.length === 0"
>
<span *ngIf="!exportLoading"><i class="bi bi-download me-1"></i> Exportar</span>
<span *ngIf="exportLoading"><span class="spinner-border spinner-border-sm me-2"></span> Exportando...</span>
</button>
</div>
<div class="bulk-actions" *ngIf="filter === 'lidas'">
<button
type="button"
class="bulk-btn"
(click)="markAllAsUnread()"
[disabled]="bulkUnreadLoading || filteredNotifications.length === 0"
>
<span *ngIf="!bulkUnreadLoading"><i class="bi bi-arrow-counterclockwise me-1"></i> Restaurar selecionadas/todas</span>
<span *ngIf="bulkUnreadLoading"><span class="spinner-border spinner-border-sm me-2"></span> Restaurando...</span>
</button>
</div>
</div>
</div>
<div class="state-container" *ngIf="loading">
<div class="spinner-border text-primary" role="status"></div>
<p>Atualizando...</p>
</div>
<div class="state-container error" *ngIf="!loading && error">
<i class="bi bi-wifi-off"></i>
<p>Não foi possível carregar as notificações.</p>
</div>
<div class="empty-state-large" *ngIf="!loading && !error && filteredNotifications.length === 0">
<div class="illustration">
<i class="bi bi-check-circle-fill"></i>
</div>
<h3>Tudo em dia!</h3>
<p *ngIf="filter === 'todas'">Não há notificações no momento.</p>
<p *ngIf="filter !== 'todas'">Nenhuma notificação neste filtro.</p>
</div>
<div class="notif-list" *ngIf="!loading && !error && filteredNotifications.length > 0">
<div
class="list-item"
*ngFor="let n of filteredNotifications"
[class.is-read]="n.lida"
[class.is-danger]="isVencido(n)"
[class.is-warning]="isAVencer(n)"
>
<div class="status-strip"></div>
<label class="item-select">
<input type="checkbox" [checked]="isSelected(n)" (change)="toggleSelection(n)" />
<span></span>
</label>
<div class="item-icon">
<i
class="bi"
[class.bi-x-circle-fill]="isVencido(n)"
[class.bi-clock-fill]="isAVencer(n)"
[class.bi-check2-circle]="isAutoRenew(n)">
</i>
</div>
<div class="item-content">
<div class="content-top">
<h4 class="item-title">
{{ n.linha || 'Linha Desconhecida' }}
<span class="separator"></span>
<span class="item-client">{{ n.cliente || '-' }}</span>
</h4>
<div class="date-stack">
<span class="date-pill green">Efetivação: {{ formatDateLabel(n.dtEfetivacaoServico) }}</span>
<span class="date-pill red">Término: {{ formatDateLabel(n.dtTerminoFidelizacao) }}</span>
</div>
</div>
<div class="item-meta-grid">
<div class="meta-row">
<span class="meta-label">Conta</span>
<span class="meta-value">{{ n.conta || '-' }}</span>
</div>
<div class="meta-row">
<span class="meta-label">Usuário</span>
<span class="meta-value">{{ n.usuario || '-' }}</span>
</div>
<div class="meta-row">
<span class="meta-label">Plano</span>
<span class="meta-value">{{ n.planoContrato || '-' }}</span>
</div>
<div class="meta-row">
<span class="badge-tag" [class.danger]="isVencido(n)" [class.warn]="isAVencer(n)" [class.info]="isAutoRenew(n)">
{{ getStatusLabel(n) }}
</span>
</div>
</div>
</div>
<div class="item-actions">
<button
type="button"
class="btn-action"
[title]="n.lida ? 'Marcar como não lida' : 'Marcar como lida'"
(click)="n.lida ? markAsUnread(n) : markAsRead(n)"
>
<i class="bi" [class.bi-arrow-counterclockwise]="n.lida" [class.bi-check2]="!n.lida"></i>
<span class="d-none d-md-inline">{{ n.lida ? 'Restaurar' : 'Marcar lida' }}</span>
</button>
<button
type="button"
class="btn-action ghost"
*ngIf="n.vigenciaLineId || n.linha"
title="Abrir na página de vigência"
(click)="goToVigencia(n)"
>
<i class="bi bi-box-arrow-up-right"></i>
<span class="d-none d-md-inline">Abrir vigência</span>
</button>
<button
type="button"
class="btn-action renew"
*ngIf="isAVencer(n)"
title="Programar renovação automática por mais 2 anos"
(click)="renewFromNotification(n)"
[disabled]="isRenewing(n)"
>
<i class="bi bi-arrow-repeat"></i>
<span class="d-none d-md-inline">{{ isRenewing(n) ? 'Aguarde...' : 'Renovar +2' }}</span>
</button>
</div>
</div>
</div>
</div>
</div>
</section>