line-gestao-frontend/src/app/pages/troca-numero/troca-numero.html

352 lines
15 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: 10000;">
<div #successToast class="toast text-bg-success border-0 shadow" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header border-bottom-0">
<strong class="me-auto text-primary">LineGestão</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Fechar"></button>
</div>
<div class="toast-body bg-white rounded-bottom text-dark">
{{ toastMessage }}
</div>
</div>
</div>
<section class="troca-page">
<span class="page-blob blob-1" aria-hidden="true"></span>
<span class="page-blob blob-2" aria-hidden="true"></span>
<span class="page-blob blob-3" aria-hidden="true"></span>
<span class="page-blob blob-4" aria-hidden="true"></span>
<div class="container-troca">
<div class="troca-card" data-animate>
<div class="troca-header">
<div class="header-row-top">
<div class="title-badge" data-animate>
<i class="bi bi-arrow-left-right"></i> TROCA DE NÚMERO
</div>
<div class="header-title" data-animate>
<h5 class="title mb-0">Troca de Número</h5>
<small class="subtitle">Registros importados da aba “TROCA DE NÚMERO”</small>
</div>
<div class="header-actions d-flex gap-2 justify-content-end" data-animate>
<button type="button" class="btn btn-brand btn-sm" (click)="onCreate()" [disabled]="loading">
<i class="bi bi-plus-circle me-1"></i> Nova Troca
</button>
</div>
</div>
<div class="troca-kpis mt-4 animate-fade-in">
<div class="kpi">
<span class="lbl">Motivos</span>
<span class="val">
<span *ngIf="loading" class="spinner-border spinner-border-sm text-muted"></span>
<span *ngIf="!loading">{{ total || 0 }}</span>
</span>
</div>
<div class="kpi">
<span class="lbl">Registros</span>
<span class="val">
<span *ngIf="loading" class="spinner-border spinner-border-sm text-muted"></span>
<span *ngIf="!loading">{{ groupLoadedRecords || 0 }}</span>
</span>
</div>
<div class="kpi">
<span class="lbl text-brand">Trocas</span>
<span class="val text-brand">
<span *ngIf="loading" class="spinner-border spinner-border-sm text-muted"></span>
<span *ngIf="!loading">{{ groupTotalTrocas || 0 }}</span>
</span>
</div>
<div class="kpi">
<span class="lbl text-success">ICCID</span>
<span class="val text-success">
<span *ngIf="loading" class="spinner-border spinner-border-sm text-muted"></span>
<span *ngIf="!loading">{{ groupTotalIccids || 0 }}</span>
</span>
</div>
</div>
<div class="controls mt-3 mb-2" data-animate>
<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" [class.text-brand]="loading"></i>
</span>
<input class="form-control" placeholder="Pesquisar (linha, ICCID, motivo, observação)..." [(ngModel)]="searchTerm" (ngModelChange)="onSearch()" />
<button class="btn btn-outline-secondary btn-clear" type="button" (click)="clearSearch()" *ngIf="searchTerm">
<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="letter-spacing: 0.5px; font-size: 0.75rem;">Itens por pág:</span>
<div class="select-wrapper">
<select class="form-select form-select-sm select-glass" [(ngModel)]="pageSize" (change)="onPageSizeChange()" [disabled]="loading">
<option [ngValue]="10">10</option>
<option [ngValue]="20">20</option>
<option [ngValue]="50">50</option>
<option [ngValue]="100">100</option>
</select>
<i class="bi bi-chevron-down select-icon"></i>
</div>
</div>
</div>
</div>
<div class="troca-body">
<div class="groups-container">
<div class="text-center p-5" *ngIf="loading">
<span class="spinner-border text-brand"></span>
</div>
<div class="empty-group" *ngIf="!loading && pagedGroups.length === 0">
Nenhum dado encontrado.
</div>
<div class="group-list" *ngIf="!loading">
<div *ngFor="let g of pagedGroups" class="client-group-card" [class.expanded]="expandedGroup === g.key">
<div class="group-header" (click)="toggleGroup(g.key)">
<div class="group-info">
<h6 class="mb-0 fw-bold text-dark td-clip" [title]="g.key">{{ g.key }}</h6>
<div class="group-badges">
<span class="badge-pill total">{{ g.total }} Registros</span>
<span class="badge-pill swap" *ngIf="g.trocas > 0">{{ g.trocas }} Trocas</span>
<span class="badge-pill ok" *ngIf="g.comIccid > 0">{{ g.comIccid }} ICCID</span>
<span class="badge-pill warn" *ngIf="g.semIccid > 0">{{ g.semIccid }} Sem ICCID</span>
</div>
</div>
<div class="group-toggle-icon"><i class="bi bi-chevron-down"></i></div>
</div>
<div class="group-body" *ngIf="expandedGroup === g.key">
<div class="d-flex justify-content-between align-items-center px-4 py-2 border-bottom bg-white">
<small class="text-muted fw-bold">Registros do Motivo</small>
<span class="chip-muted"><i class="bi bi-info-circle me-1"></i> Use o botão à direita para editar</span>
</div>
<div class="table-wrap inner-table-wrap">
<table class="table table-modern align-middle text-center mb-0">
<thead>
<tr>
<th>ITEM</th>
<th>LINHA ANTIGA</th>
<th>LINHA NOVA</th>
<th>ICCID</th>
<th>DATA TROCA</th>
<th>OBSERVAÇÃO</th>
<th style="min-width: 80px;">AÇÕES</th>
</tr>
</thead>
<tbody>
<tr *ngIf="groupRows.length === 0">
<td colspan="7" class="text-center py-4 empty-state text-muted fw-bold">Nenhum registro.</td>
</tr>
<tr *ngFor="let r of groupRows; trackBy: trackById" class="table-row-item">
<td class="text-muted fw-bold">{{ r.item || '-' }}</td>
<td class="text-dark">{{ r.linhaAntiga || '-' }}</td>
<td class="fw-black text-blue">{{ r.linhaNova || '-' }}</td>
<td class="small font-monospace">{{ r.iccid || '-' }}</td>
<td class="text-muted small fw-bold">{{ displayValue('dataTroca', r.dataTroca) }}</td>
<td class="td-clip" style="max-width: 360px;" [title]="r.observacao">{{ r.observacao || '-' }}</td>
<td>
<div class="action-group justify-content-center">
<button class="btn-icon primary" (click)="onEditar(r)" title="Editar Registro">
<i class="bi bi-pencil-square"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="troca-footer">
<div class="small text-muted fw-bold">Mostrando {{ pageStart }}{{ pageEnd }} de {{ total }} Motivos</div>
<nav>
<ul class="pagination pagination-sm mb-0 pagination-modern">
<li class="page-item" [class.disabled]="page === 1 || loading">
<button class="page-link" (click)="goToPage(page - 1)">Anterior</button>
</li>
<li class="page-item" *ngFor="let p of pageNumbers" [class.active]="p === page">
<button class="page-link" (click)="goToPage(p)">{{ p }}</button>
</li>
<li class="page-item" [class.disabled]="page === totalPages || loading">
<button class="page-link" (click)="goToPage(page + 1)">Próxima</button>
</li>
</ul>
</nav>
</div>
</div>
</div>
</section>
<div class="modal-backdrop-custom" *ngIf="editOpen || createOpen" (click)="closeEdit(); closeCreate()"></div>
<!-- EDIT MODAL -->
<div class="modal-custom" *ngIf="editOpen">
<div class="modal-card modal-lg" (click)="$event.stopPropagation()">
<div class="modal-header">
<div class="modal-title">
<span class="icon-bg primary-soft"><i class="bi bi-pencil-square"></i></span>
Editar Troca de Número
</div>
<div class="d-flex align-items-center gap-2">
<button class="btn btn-glass btn-sm" (click)="closeEdit()" [disabled]="editSaving">
<i class="bi bi-x-lg me-1"></i> Cancelar
</button>
<button class="btn btn-brand btn-sm" (click)="saveEdit()" [disabled]="!editModel || editSaving">
<span *ngIf="!editSaving"><i class="bi bi-check2-circle me-1"></i> Salvar</span>
<span *ngIf="editSaving"><span class="spinner-border spinner-border-sm me-2"></span> Salvando...</span>
</button>
</div>
</div>
<div class="modal-body modern-body bg-light-gray">
<ng-container *ngIf="editModel; else editLoadingTpl">
<div class="details-dashboard">
<div class="detail-box w-100">
<div class="box-header"><span><i class="bi bi-card-text me-2"></i> Informações</span></div>
<div class="box-body">
<div class="form-grid">
<div class="form-field">
<label>Item</label>
<input class="form-control form-control-sm" [(ngModel)]="editModel.item" />
</div>
<div class="form-field">
<label>Data Troca</label>
<input class="form-control form-control-sm" type="date" [(ngModel)]="editModel.dataTroca" />
</div>
<div class="form-field">
<label>Linha Antiga</label>
<input class="form-control form-control-sm" [(ngModel)]="editModel.linhaAntiga" />
</div>
<div class="form-field">
<label>Linha Nova</label>
<input class="form-control form-control-sm fw-bold text-blue" [(ngModel)]="editModel.linhaNova" />
</div>
<div class="form-field span-2">
<label>ICCID</label>
<input class="form-control form-control-sm font-monospace" [(ngModel)]="editModel.iccid" />
</div>
<div class="form-field span-2">
<label>Motivo</label>
<input class="form-control form-control-sm" [(ngModel)]="editModel.motivo" />
</div>
<div class="form-field span-2">
<label>Observação</label>
<textarea class="form-control form-control-sm" rows="3" [(ngModel)]="editModel.observacao"></textarea>
</div>
</div>
</div>
</div>
</div>
</ng-container>
<ng-template #editLoadingTpl>
<div class="p-5 text-center text-muted">Preparando edição...</div>
</ng-template>
</div>
</div>
</div>
<!-- CREATE MODAL -->
<div class="modal-custom" *ngIf="createOpen">
<div class="modal-card modal-lg" (click)="$event.stopPropagation()">
<div class="modal-header">
<div class="modal-title">
<span class="icon-bg brand-soft"><i class="bi bi-plus-lg"></i></span>
Nova Troca
</div>
<div class="d-flex align-items-center gap-2">
<button class="btn btn-glass btn-sm" (click)="closeCreate()" [disabled]="createSaving">
<i class="bi bi-x-lg me-1"></i> Cancelar
</button>
<button class="btn btn-brand btn-sm" (click)="saveCreate()" [disabled]="createSaving">
<span *ngIf="!createSaving"><i class="bi bi-check2-circle me-1"></i> Criar</span>
<span *ngIf="createSaving"><span class="spinner-border spinner-border-sm me-2"></span> Salvando...</span>
</button>
</div>
</div>
<div class="modal-body modern-body bg-light-gray">
<div class="details-dashboard">
<div class="detail-box w-100">
<div class="box-header"><span><i class="bi bi-pencil me-2"></i> Preencha os dados</span></div>
<div class="box-body">
<div class="form-grid">
<div class="form-field">
<label>Item</label>
<input class="form-control form-control-sm" [(ngModel)]="createModel.item" />
</div>
<div class="form-field">
<label>Data Troca</label>
<input class="form-control form-control-sm" type="date" [(ngModel)]="createModel.dataTroca" />
</div>
<div class="form-field">
<label>Linha Antiga</label>
<input class="form-control form-control-sm" [(ngModel)]="createModel.linhaAntiga" />
</div>
<div class="form-field">
<label>Linha Nova</label>
<input class="form-control form-control-sm fw-bold text-blue" [(ngModel)]="createModel.linhaNova" />
</div>
<div class="form-field span-2">
<label>ICCID</label>
<input class="form-control form-control-sm font-monospace" [(ngModel)]="createModel.iccid" />
</div>
<div class="form-field span-2">
<label>Motivo</label>
<input class="form-control form-control-sm" [(ngModel)]="createModel.motivo" placeholder="Ex: perda/roubo, troca de colaborador..." />
</div>
<div class="form-field span-2">
<label>Observação</label>
<textarea class="form-control form-control-sm" rows="3" [(ngModel)]="createModel.observacao"></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>