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

196 lines
9.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="toast-container position-fixed top-0 end-0 p-3" style="z-index: 12000;">
<div class="toast border-0 shadow" [class.show]="toastOpen" [class.text-bg-success]="toastType === 'success'" [class.text-bg-danger]="toastType === 'danger'">
<div class="toast-header border-bottom-0">
<strong class="me-auto">LineGestão</strong>
<button type="button" class="btn-close" (click)="hideToast()"></button>
</div>
<div class="toast-body bg-white rounded-bottom text-dark fw-bold">{{ toastMessage }}</div>
</div>
</div>
<section class="vigencia-page">
<span class="page-blob blob-1"></span>
<span class="page-blob blob-2"></span>
<span class="page-blob blob-3"></span>
<div class="container-geral-responsive">
<div class="geral-card">
<div class="geral-header">
<div class="header-row-top">
<div class="title-badge"><i class="bi bi-calendar2-week"></i> VIGÊNCIA</div>
<div class="header-title">
<h5 class="title">GESTÃO DE VIGÊNCIA</h5>
<small class="subtitle">Controle de contratos e fidelização</small>
</div>
<div class="header-actions d-flex gap-2 justify-content-end">
<button class="btn btn-glass btn-sm" (click)="onExport()" [disabled]="loading || exporting">
<span *ngIf="!exporting"><i class="bi bi-download me-1"></i> Exportar</span>
<span *ngIf="exporting"><span class="spinner-border spinner-border-sm me-2"></span> Exportando...</span>
</button>
<button *ngIf="isSysAdmin" class="btn btn-brand btn-sm" (click)="openCreate()">
<i class="bi bi-plus-circle me-1"></i> Nova Vigência
</button>
</div>
</div>
<div class="mureg-kpis mt-4 animate-fade-in" *ngIf="viewMode === 'groups'">
<div class="kpi">
<span class="lbl">Total Clientes</span>
<span class="val">{{ kpiTotalClientes }}</span>
</div>
<div class="kpi">
<span class="lbl">Total Linhas</span>
<span class="val">{{ kpiTotalLinhas }}</span>
</div>
<div class="kpi">
<span class="lbl text-danger">Total Vencidos</span>
<span class="val text-danger">{{ kpiTotalVencidos }}</span>
</div>
</div>
<div class="controls mt-3 mb-2 d-flex flex-wrap gap-3 align-items-center justify-content-between">
<div class="input-group input-group-sm search-group">
<span class="input-group-text">
<i class="bi" [class.bi-search]="!loading" [class.bi-hourglass-split]="loading"></i>
</span>
<input
type="search"
class="form-control"
placeholder="Pesquisar..."
inputmode="search"
enterkeyhint="search"
autocomplete="off"
[(ngModel)]="search"
(ngModelChange)="onSearchChange()">
<button
class="btn btn-outline-secondary btn-clear"
type="button"
*ngIf="search"
(click)="clearFilters()">
<i class="bi bi-x-lg"></i>
</button>
</div>
<div class="page-size d-flex align-items-center gap-2">
<span class="text-muted small fw-bold text-uppercase" style="font-size: 0.75rem;">Itens por pág:</span>
<app-select class="select-glass" size="sm" [options]="pageSizeOptions" [(ngModel)]="pageSize" (ngModelChange)="fetch(1)" [disabled]="loading" style="width: 80px;"></app-select>
</div>
</div>
</div>
<div class="geral-body">
<div class="groups-container">
<div class="text-center p-5" *ngIf="loading">
<div class="spinner-border text-brand" role="status"></div>
</div>
<div class="empty-state text-center p-5" *ngIf="!loading && groups.length === 0">
Nenhum dado encontrado.
</div>
<div *ngFor="let g of groups" class="client-group-card mb-3" [class.expanded]="expandedGroup === g.cliente">
<div class="group-header" (click)="toggleGroup(g)">
<div class="group-info">
<h6 class="group-title mb-0">{{ g.cliente }}</h6>
<div class="group-badges mt-1">
<span class="badge-pill total">{{ g.linhas }} Registros</span>
<span class="badge-pill danger" *ngIf="g.vencidos > 0">{{ g.vencidos }} Vencidos</span>
<span class="badge-pill ok" *ngIf="g.linhas - g.vencidos > 0">{{ g.linhas - g.vencidos }} Ativos</span>
</div>
</div>
<div class="group-toggle-icon"><i class="bi bi-chevron-down"></i></div>
</div>
<div class="group-body" *ngIf="expandedGroup === g.cliente">
<div class="group-body-top d-flex justify-content-between align-items-center px-4 py-2 border-bottom bg-white">
<small class="text-muted fw-bold">Linhas do Cliente</small>
<span class="chip-muted">Total: {{ g.total | currency:'BRL' }}</span>
</div>
<div class="text-center p-4" *ngIf="expandedLoading">
<div class="spinner-border spinner-border-sm text-brand"></div>
</div>
<div class="table-wrap inner-table-wrap" *ngIf="!expandedLoading">
<table class="table table-modern align-middle text-center mb-0">
<thead>
<tr>
<th>ITEM</th>
<th>LINHA</th>
<th>CONTA</th>
<th>USUÁRIO</th>
<th class="plano-col">PLANO</th>
<th>EFETIVAÇÃO</th>
<th>VENCIMENTO</th>
<th class="text-end">TOTAL</th>
<th class="actions-col">AÇÕES</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of groupRows" class="table-row-item">
<td class="text-muted fw-bold">{{ row.item }}</td>
<td class="fw-black text-blue">{{ row.linha }}</td>
<td class="text-dark small">{{ row.conta || '-' }}</td>
<td class="text-muted small">{{ row.usuario || '-' }}</td>
<td class="text-muted small td-clip plano-col" [title]="row.planoContrato">{{ row.planoContrato || '-' }}</td>
<td class="text-muted small fw-bold">
{{ row.dtEfetivacaoServico ? (row.dtEfetivacaoServico | date:'dd/MM/yyyy') : '-' }}
</td>
<td class="fw-bold" [class.text-danger]="isVencido(row.dtTerminoFidelizacao)">
{{ row.dtTerminoFidelizacao ? (row.dtTerminoFidelizacao | date:'dd/MM/yyyy') : '-' }}
</td>
<td class="text-end fw-black text-dark">
{{ (row.total || 0) | currency:'BRL' }}
</td>
<td class="actions-col">
<div class="action-group justify-content-center">
<span class="renew-chip" *ngIf="row.autoRenewYears">{{ getRenewalBadge(row) }}</span>
<button
*ngIf="isAVencer(row.dtTerminoFidelizacao)"
class="btn btn-primary btn-xs"
(click)="scheduleAutoRenew(row)"
title="Renovar por mais 2 anos">
Renovar +2 anos
</button>
<button class="btn-icon primary" (click)="openDetails(row)" title="Ver Detalhes"><i class="bi bi-eye"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon primary" (click)="openEdit(row)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="openDelete(row)" title="Excluir"><i class="bi bi-trash"></i></button>
</div>
</td>
</tr>
<tr *ngIf="groupRows.length === 0">
<td colspan="9" class="text-center py-4 text-muted fw-bold">Nenhuma linha encontrada.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="geral-footer">
<div class="small text-muted fw-bold">Mostrando {{ (page - 1) * pageSize + 1 }}{{ (page * pageSize) > total ? total : (page * pageSize) }} de {{ total }} Clientes</div>
<nav>
<ul class="pagination pagination-sm mb-0 pagination-modern">
<li class="page-item" [class.disabled]="page <= 1"><button class="page-link" (click)="fetch(page - 1)">Anterior</button></li>
<li class="page-item active"><button class="page-link">{{ page }}</button></li>
<li class="page-item" [class.disabled]="page >= totalPages"><button class="page-link" (click)="fetch(page + 1)">Próxima</button></li>
</ul>
</nav>
</div>
</div>
</div>
</section>
<app-vigencia-modals [vm]="$any(vm)"></app-vigencia-modals>