|
|
|
|
@ -3,6 +3,7 @@
|
|
|
|
|
{% block title %}Client Dashboard - OutsideTheBox{% endblock %} |
|
|
|
|
|
|
|
|
|
{% block portal_content %} |
|
|
|
|
<form id="portal-invoice-download-form" method="post" action="/portal/invoices/download-all"> |
|
|
|
|
<div class="portal-page-header"> |
|
|
|
|
<div> |
|
|
|
|
<h1 class="portal-page-title">Client Dashboard</h1> |
|
|
|
|
@ -13,7 +14,7 @@
|
|
|
|
|
<div class="portal-toolbar" style="display:flex;flex-direction:column;align-items:flex-end;gap:10px;"> |
|
|
|
|
<div style="display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;"> |
|
|
|
|
<a class="portal-btn primary" href="/portal/services">Services Here</a> |
|
|
|
|
<a class="portal-btn primary" href="/portal/invoices/download-all">Download All Invoices</a> |
|
|
|
|
<button type="submit" class="portal-btn primary" style="border:0;cursor:pointer;">Download All Invoices</button> |
|
|
|
|
<a class="portal-btn" href="mailto:support@outsidethebox.top?subject=Customer%20Support">Customer Support</a> |
|
|
|
|
<a class="portal-btn" href="/portal/logout">Logout</a> |
|
|
|
|
</div> |
|
|
|
|
@ -56,6 +57,7 @@
|
|
|
|
|
<table class="portal-table"> |
|
|
|
|
<thead> |
|
|
|
|
<tr> |
|
|
|
|
<th style="width:44px;"><input type="checkbox" id="select-all-invoices" aria-label="Select all invoices"></th> |
|
|
|
|
<th>Invoice</th> |
|
|
|
|
<th>Status</th> |
|
|
|
|
<th>Created</th> |
|
|
|
|
@ -67,6 +69,9 @@
|
|
|
|
|
<tbody> |
|
|
|
|
{% for row in invoices %} |
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<input type="checkbox" class="invoice-select" name="invoice_ids" value="{{ row.id }}" aria-label="Select invoice {{ row.invoice_number or row.id }}"> |
|
|
|
|
</td> |
|
|
|
|
<td> |
|
|
|
|
<a class="invoice-link" href="/portal/invoice/{{ row.id }}"> |
|
|
|
|
{{ row.invoice_number or ("INV-" ~ row.id) }} |
|
|
|
|
@ -96,18 +101,49 @@
|
|
|
|
|
</tr> |
|
|
|
|
{% else %} |
|
|
|
|
<tr> |
|
|
|
|
<td colspan="6">No invoices available.</td> |
|
|
|
|
<td colspan="7">No invoices available.</td> |
|
|
|
|
</tr> |
|
|
|
|
{% endfor %} |
|
|
|
|
</tbody> |
|
|
|
|
</table> |
|
|
|
|
</div> |
|
|
|
|
</form> |
|
|
|
|
{% endblock %} |
|
|
|
|
|
|
|
|
|
{% block scripts %} |
|
|
|
|
<script> |
|
|
|
|
(function() { |
|
|
|
|
setTimeout(function() { window.location.reload(); }, 20000); |
|
|
|
|
const selectAll = document.getElementById("select-all-invoices"); |
|
|
|
|
const invoiceChecks = Array.from(document.querySelectorAll(".invoice-select")); |
|
|
|
|
|
|
|
|
|
function anyChecked() { |
|
|
|
|
return invoiceChecks.some(function(cb) { return cb.checked; }); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (selectAll) { |
|
|
|
|
selectAll.addEventListener("change", function() { |
|
|
|
|
invoiceChecks.forEach(function(cb) { |
|
|
|
|
cb.checked = selectAll.checked; |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
invoiceChecks.forEach(function(cb) { |
|
|
|
|
cb.addEventListener("change", function() { |
|
|
|
|
if (!selectAll) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const checkedCount = invoiceChecks.filter(function(x) { return x.checked; }).length; |
|
|
|
|
selectAll.checked = checkedCount === invoiceChecks.length && invoiceChecks.length > 0; |
|
|
|
|
selectAll.indeterminate = checkedCount > 0 && checkedCount < invoiceChecks.length; |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
setTimeout(function() { |
|
|
|
|
if (!anyChecked()) { |
|
|
|
|
window.location.reload(); |
|
|
|
|
} |
|
|
|
|
}, 20000); |
|
|
|
|
})(); |
|
|
|
|
</script> |
|
|
|
|
{% endblock %} |
|
|
|
|
|