QrRapido/Views/Admin/Index.cshtml
Ricardo Carneiro 16a9720a12
All checks were successful
Deploy QR Rapido / test (push) Successful in 59s
Deploy QR Rapido / build-and-push (push) Successful in 9m57s
Deploy QR Rapido / deploy-staging (push) Has been skipped
Deploy QR Rapido / deploy-production (push) Successful in 2m11s
feat: qrcode por creditos.
2026-01-26 20:13:45 -03:00

162 lines
6.7 KiB
Plaintext

@model List<QRRapidoApp.Models.Order>
@{
ViewData["Title"] = "Admin - Pedidos Pendentes";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container py-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3"><i class="fas fa-tasks me-2"></i>Pedidos PIX Pendentes</h1>
<button onclick="window.location.reload()" class="btn btn-outline-primary btn-sm">
<i class="fas fa-sync-alt"></i> Atualizar
</button>
</div>
@if (Model == null || !Model.Any())
{
<div class="alert alert-success text-center py-5">
<i class="fas fa-check-circle fa-3x mb-3"></i>
<h4>Tudo limpo!</h4>
<p>Não há pedidos pendentes no momento.</p>
</div>
}
else
{
<div class="card shadow-sm">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="bg-light">
<tr>
<th class="ps-4">Data</th>
<th>Usuário</th>
<th>Valor</th>
<th>Créditos</th>
<th>Identificador (PIX)</th>
<th class="text-end pe-4">Ações</th>
</tr>
</thead>
<tbody>
@foreach (var order in Model)
{
<tr id="row-@order.Id">
<td class="ps-4 small text-muted">@order.CreatedAt.ToLocalTime().ToString("dd/MM/yyyy HH:mm")</td>
<td>
<div class="fw-bold">@order.UserEmail</div>
<div class="small text-muted text-truncate" style="max-width: 150px;" title="@order.UserId">ID: @order.UserId</div>
</td>
<td class="text-primary fw-bold">R$ @order.Amount.ToString("F2")</td>
<td>
<span class="badge bg-info text-dark">@order.CreditsAmount Créditos</span>
</td>
<td>
<code class="bg-light px-2 py-1 rounded border">@order.PixCode</code>
</td>
<td class="text-end pe-4">
<button class="btn btn-success btn-sm me-2" onclick="approveOrder('@order.Id')">
<i class="fas fa-check"></i> Aprovar
</button>
<button class="btn btn-outline-danger btn-sm" onclick="rejectOrder('@order.Id')">
<i class="fas fa-times"></i>
</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
</div>
@section Scripts {
<script>
async function approveOrder(orderId) {
if (!confirm('Confirmar recebimento do PIX e liberar créditos?')) return;
const row = document.getElementById(`row-${orderId}`);
const btn = row.querySelector('.btn-success');
const originalText = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';
try {
const response = await fetch(`/api/Admin/Orders/${orderId}/Approve`, {
method: 'POST'
});
if (response.ok) {
// Success animation
row.classList.add('table-success');
setTimeout(() => {
row.style.transition = 'opacity 0.5s ease';
row.style.opacity = '0';
setTimeout(() => row.remove(), 500);
}, 500);
showToast('Créditos liberados com sucesso!', 'success');
} else {
const data = await response.json();
alert('Erro: ' + (data.error || 'Falha ao aprovar'));
btn.disabled = false;
btn.innerHTML = originalText;
}
} catch (error) {
console.error(error);
alert('Erro de conexão');
btn.disabled = false;
btn.innerHTML = originalText;
}
}
async function rejectOrder(orderId) {
if (!confirm('Tem certeza que deseja REJEITAR este pedido?')) return;
const row = document.getElementById(`row-${orderId}`);
try {
const response = await fetch(`/api/Admin/Orders/${orderId}/Reject`, {
method: 'POST'
});
if (response.ok) {
row.classList.add('table-danger');
setTimeout(() => {
row.style.opacity = '0';
setTimeout(() => row.remove(), 500);
}, 500);
} else {
alert('Erro ao rejeitar');
}
} catch (error) {
console.error(error);
}
}
function showToast(message, type) {
// Reusing toast logic if available or simple alert
// Creating temporary toast container if needed
let toastContainer = document.getElementById('toast-container');
if (!toastContainer) {
toastContainer = document.createElement('div');
toastContainer.id = 'toast-container';
toastContainer.className = 'toast-container position-fixed top-0 start-0 p-3';
toastContainer.style.zIndex = '1060';
toastContainer.style.marginTop = '80px';
document.body.appendChild(toastContainer);
}
const toastEl = document.createElement('div');
toastEl.className = `toast align-items-center text-white bg-${type} border-0`;
toastEl.innerHTML = `
<div class="d-flex">
<div class="toast-body">${message}</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
</div>`;
toastContainer.appendChild(toastEl);
const toast = new bootstrap.Toast(toastEl);
toast.show();
}
</script>
}