Files
php_assessment_1/licenseListing.php
T
2025-08-07 16:34:00 +01:00

257 lines
10 KiB
PHP

<style>
.dark-header thead th {
background-color: #343a40;
/* Dark gray background */
color: white;
/* White text color */
}
.bulk-actions {
margin-bottom: 15px;
padding: 10px;
background-color: #f8f9fa;
border-radius: 5px;
display: none;
}
.bulk-actions.show {
display: block;
}
</style>
<div class="container">
<h2 class="text-left">Licenses &nbsp; <a class="btn btn-primary" href="/admin/license/add">Add</a></h2>
<!-- Bulk Actions Form -->
<div class="bulk-actions" id="bulkActions">
<form action="/admin/license/list/multiselect" method="POST" onsubmit="return confirmBulkDelete()">
<div class="d-flex align-items-center">
<span class="mr-3"><strong>Selected items:</strong> <span id="selectedCount">0</span></span>
<button type="submit" name="delete" class="btn btn-danger btn-sm mr-2">
<i class="fa fa-trash"></i> Delete Selected
</button>
<button type="button" class="btn btn-secondary btn-sm" onclick="clearSelection()">
Clear Selection
</button>
</div>
<input type="hidden" name="selected_items" id="selectedItems" value="">
</form>
</div>
<div class="row mt-2 mb-2">
<div class="col-md-10 col-md-offset-1">
<form action="?" method="GET" class="form-inline">
<div class="input-group mr-2 mb-2">
<label class="mr-2" for="relationship_num">Relationship #</label>
<input id="relationship_num" type="text" name="relationship_num" class="form-control" placeholder="Enter Relationship #"
value="<?php echo htmlspecialchars($data['relationship_num'] ?? ''); ?>">
</div>
<div class="input-group mr-2 mb-2">
<label class="mr-2" for="email">Email</label>
<input id="email" type="text" name="email" class="form-control" placeholder="Fuzzy email search..."
value="<?php echo htmlspecialchars($data['email_search'] ?? ''); ?>">
</div>
<!-- Preserve cursor parameter when searching -->
<input type="hidden" name="cursor" value="0">
<span class="input-group-btn mb-2">
<button class="btn btn-primary mr-2" type="submit">Search</button>
<a class="btn btn-secondary" href="/admin/license">Clear</a>
</span>
</form>
</div><!-- /.col-md-10 -->
</div><!-- /.row -->
<!-- Table Responsive Wrapper -->
<div class="table-responsive">
<table class="table table-hover dark-header">
<thead>
<tr>
<th>
<input type="checkbox" id="selectAll" onchange="toggleSelectAll()">
<label for="selectAll" class="ml-1">Select All</label>
</th>
<th>ID</th>
<th>Relationship #</th>
<th>Email</th>
<th>API Key</th>
<th>IP</th>
<th>Status</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<?php foreach ($data['data'] as $key => $value) {
echo ' <tr>';
echo ' <td><input type="checkbox" class="item-checkbox" value="' . $value->id . '" onchange="updateBulkActions()"></td>';
echo ' <td>' . $value->id . ' <br/><a class=" text-info" href="/admin/license/edit/' . $value->id . '">edit</a> <a class="text-danger" href="/admin/license/delete/' . $value->id . '">delete</a></td>';
echo ' <td>' . $value->relationship_num . ' </td>';
echo ' <td>' . $value->email . ' </td>';
echo ' <td>' . $value->apikey . ' </td>';
echo ' <td>' . $value->ip . ' </td>';
echo ' <td>' . $value->status . ' </td>';
echo ' <td>' . $value->created_at . ' </td>';
echo '</tr>';
}
?>
</tbody>
</table>
</div>
<?php
// Retrieve cursor pagination parameters
$total = $data['total'];
$currentPage = $data['page'];
$perPage = 10;
$lastId = isset($data['id']) ? $data['id'] : 0;
$currentCursor = isset($_GET['cursor']) ? intval($_GET['cursor']) : 0;
$relationshipNum = isset($_GET['relationship_num']) ? $_GET['relationship_num'] : '';
$emailSearch = isset($_GET['email']) ? $_GET['email'] : '';
// Build query parameters for pagination links
$queryParams = [];
if (!empty($relationshipNum)) {
$queryParams['relationship_num'] = $relationshipNum;
}
if (!empty($emailSearch)) {
$queryParams['email'] = $emailSearch;
}
// Helper function to build query string
function buildQueryString($params) {
return !empty($params) ? '&' . http_build_query($params) : '';
}
$queryString = buildQueryString($queryParams);
// Determine if we have previous/next pages
$hasPrevious = $currentCursor > 0;
$hasNext = count($data['data']) >= $perPage; // If we got a full page, assume there might be more
?>
<!-- Cursor-based Pagination -->
<nav aria-label="Cursor-based page navigation">
<div class="d-flex justify-content-between align-items-center">
<div class="pagination-info">
<small class="text-muted">
Showing <?= count($data['data']) ?> items
<?php if ($total > 0): ?>
(Total: <?= $total ?> items)
<?php endif; ?>
</small>
</div>
<ul class="pagination mb-0">
<?php if ($hasPrevious): ?>
<li class="page-item">
<a class="page-link" href="?cursor=0<?= $queryString ?>" aria-label="First">
<span aria-hidden="true">&laquo;&laquo;</span>
<span class="sr-only">First</span>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?cursor=<?= max(0, $currentCursor - $perPage) ?><?= $queryString ?>" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
</a>
</li>
<?php else: ?>
<li class="page-item disabled">
<span class="page-link">
<span aria-hidden="true">&laquo;&laquo;</span>
</span>
</li>
<li class="page-item disabled">
<span class="page-link">
<span aria-hidden="true">&laquo;</span>
</span>
</li>
<?php endif; ?>
<li class="page-item active">
<span class="page-link">Current</span>
</li>
<?php if ($hasNext): ?>
<li class="page-item">
<a class="page-link" href="?cursor=<?= $lastId ?><?= $queryString ?>" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Next</span>
</a>
</li>
<?php else: ?>
<li class="page-item disabled">
<span class="page-link">
<span aria-hidden="true">&raquo;</span>
</span>
</li>
<?php endif; ?>
</ul>
</div>
</nav>
</div>
<script>
function toggleSelectAll() {
const selectAll = document.getElementById('selectAll');
const checkboxes = document.querySelectorAll('.item-checkbox');
checkboxes.forEach(checkbox => {
checkbox.checked = selectAll.checked;
});
updateBulkActions();
}
function updateBulkActions() {
const checkboxes = document.querySelectorAll('.item-checkbox:checked');
const bulkActions = document.getElementById('bulkActions');
const selectedCount = document.getElementById('selectedCount');
const selectedItems = document.getElementById('selectedItems');
const selectAll = document.getElementById('selectAll');
const count = checkboxes.length;
selectedCount.textContent = count;
if (count > 0) {
bulkActions.classList.add('show');
const ids = Array.from(checkboxes).map(cb => cb.value);
selectedItems.value = ids.join(',');
} else {
bulkActions.classList.remove('show');
selectedItems.value = '';
}
// Update select all checkbox state
const allCheckboxes = document.querySelectorAll('.item-checkbox');
const checkedCheckboxes = document.querySelectorAll('.item-checkbox:checked');
if (checkedCheckboxes.length === 0) {
selectAll.indeterminate = false;
selectAll.checked = false;
} else if (checkedCheckboxes.length === allCheckboxes.length) {
selectAll.indeterminate = false;
selectAll.checked = true;
} else {
selectAll.indeterminate = true;
}
}
function clearSelection() {
const checkboxes = document.querySelectorAll('.item-checkbox');
const selectAll = document.getElementById('selectAll');
checkboxes.forEach(checkbox => {
checkbox.checked = false;
});
selectAll.checked = false;
selectAll.indeterminate = false;
updateBulkActions();
}
function confirmBulkDelete() {
const count = document.querySelectorAll('.item-checkbox:checked').length;
if (count === 0) {
alert('Please select at least one item to delete.');
return false;
}
return confirm(`Are you sure you want to delete ${count} selected license(s)? This action cannot be undone.`);
}
</script>