recreate project
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
// app/Views/rolepermission/permissionList.php
|
||||
?>
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container-fluid"
|
||||
data-permissions-endpoint="<?= esc($permissionsEndpoint ?? site_url('api/rolepermission/permissions')) ?>">
|
||||
<div class="wrapper">
|
||||
<div class="content">
|
||||
<h2 class="text-center mt-4 mb-3">List of Permissions</h2>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
<?php if (session()->getFlashdata('success')): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<?= session()->getFlashdata('success') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (session()->getFlashdata('error')): ?>
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
<?= session()->getFlashdata('error') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Header actions -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div>
|
||||
<small class="text-muted">
|
||||
<span id="permissionsTotal" class="text-muted"></span>
|
||||
</small>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="<?= site_url('rolepermission/add_permission') ?>" class="btn btn-success">
|
||||
<i class="fas fa-plus"></i> Add New Permission
|
||||
</a>
|
||||
<a href="<?= site_url('rolepermission/roles') ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-list"></i> Back to Roles
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="myTable" class="display table table-bordered table-striped align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th style="width: 90px;">ID</th>
|
||||
<th style="width: 280px;">Name</th>
|
||||
<th>Description</th>
|
||||
<th style="width: 180px;">Created</th>
|
||||
<th style="width: 180px;">Updated</th>
|
||||
<th style="width: 220px;">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted py-4">
|
||||
Loading permissions…
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="permissionsAlert" class="alert alert-danger d-none" role="alert"></div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('scripts') ?>
|
||||
<!-- Make sure DataTables JS & CSS are included in your layout (management_layout) -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const container = document.querySelector('[data-permissions-endpoint]');
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
const endpoint = container.dataset.permissionsEndpoint;
|
||||
const tableBody = document.querySelector('#myTable tbody');
|
||||
const totalLabel = document.getElementById('permissionsTotal');
|
||||
const alertBox = document.getElementById('permissionsAlert');
|
||||
|
||||
const hasDataTables = () => (
|
||||
window.jQuery && window.jQuery.fn && window.jQuery.fn.DataTable
|
||||
);
|
||||
|
||||
const destroyDataTable = () => {
|
||||
if (!hasDataTables()) return;
|
||||
if (window.jQuery.fn.DataTable.isDataTable('#myTable')) {
|
||||
window.jQuery('#myTable').DataTable().clear().destroy();
|
||||
}
|
||||
};
|
||||
|
||||
const initDataTable = () => {
|
||||
if (!hasDataTables()) return;
|
||||
window.jQuery('#myTable').DataTable({
|
||||
pageLength: 10,
|
||||
lengthMenu: [5, 10, 25, 50, 100],
|
||||
ordering: true,
|
||||
});
|
||||
};
|
||||
|
||||
const setTotal = (count) => {
|
||||
if (!totalLabel) return;
|
||||
totalLabel.textContent = `Total: ${count}`;
|
||||
};
|
||||
|
||||
const showError = (message) => {
|
||||
if (!alertBox) return;
|
||||
alertBox.textContent = message;
|
||||
alertBox.classList.remove('d-none');
|
||||
};
|
||||
|
||||
const clearError = () => {
|
||||
if (!alertBox) return;
|
||||
alertBox.textContent = '';
|
||||
alertBox.classList.add('d-none');
|
||||
};
|
||||
|
||||
const formatDateTime = (value) => {
|
||||
if (!value) return '—';
|
||||
const date = new Date(value.replace(' ', 'T'));
|
||||
if (Number.isNaN(date.valueOf())) {
|
||||
return value;
|
||||
}
|
||||
const pad = (num) => String(num).padStart(2, '0');
|
||||
const datePart = `${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${date.getFullYear()}`;
|
||||
const hasTime = /[T ]\d{2}:\d{2}/.test(String(value));
|
||||
if (!hasTime) {
|
||||
return datePart;
|
||||
}
|
||||
const timePart = `${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
||||
return `${datePart} ${timePart}`;
|
||||
};
|
||||
|
||||
const renderPermissions = (permissions) => {
|
||||
destroyDataTable();
|
||||
tableBody.innerHTML = '';
|
||||
|
||||
if (!Array.isArray(permissions) || permissions.length === 0) {
|
||||
const row = document.createElement('tr');
|
||||
const cell = document.createElement('td');
|
||||
cell.colSpan = 6;
|
||||
cell.classList.add('text-center', 'text-muted', 'py-4');
|
||||
cell.textContent = 'No permissions found.';
|
||||
row.appendChild(cell);
|
||||
tableBody.appendChild(row);
|
||||
setTotal(0);
|
||||
return;
|
||||
}
|
||||
|
||||
permissions.forEach((permission) => {
|
||||
const row = document.createElement('tr');
|
||||
|
||||
const idCell = document.createElement('td');
|
||||
idCell.textContent = permission.id ?? '';
|
||||
row.appendChild(idCell);
|
||||
|
||||
const nameCell = document.createElement('td');
|
||||
nameCell.innerHTML = `<code>${permission.name ?? ''}</code>`;
|
||||
row.appendChild(nameCell);
|
||||
|
||||
const descCell = document.createElement('td');
|
||||
descCell.textContent = permission.description ?? '';
|
||||
row.appendChild(descCell);
|
||||
|
||||
const createdCell = document.createElement('td');
|
||||
createdCell.textContent = formatDateTime(permission.created_at ?? null);
|
||||
row.appendChild(createdCell);
|
||||
|
||||
const updatedCell = document.createElement('td');
|
||||
updatedCell.textContent = formatDateTime(permission.updated_at ?? null);
|
||||
row.appendChild(updatedCell);
|
||||
|
||||
const actionsCell = document.createElement('td');
|
||||
actionsCell.innerHTML = `
|
||||
<a href="<?= site_url('rolepermission/edit_permission/') ?>${permission.id}"
|
||||
class="btn btn-sm btn-warning me-1">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>
|
||||
<form action="<?= site_url('rolepermission/delete_permission/') ?>${permission.id}" method="post" class="d-inline">
|
||||
<?= csrf_field() ?>
|
||||
<button type="submit" class="btn btn-sm btn-danger"
|
||||
onclick="return confirm('Delete permission \"${permission.name ?? ''}\"? This cannot be undone.');">
|
||||
<i class="fas fa-trash-alt"></i> Delete
|
||||
</button>
|
||||
</form>
|
||||
`;
|
||||
row.appendChild(actionsCell);
|
||||
|
||||
tableBody.appendChild(row);
|
||||
});
|
||||
|
||||
setTotal(permissions.length);
|
||||
initDataTable();
|
||||
};
|
||||
|
||||
const fetchPermissions = () => {
|
||||
if (!endpoint) return;
|
||||
|
||||
tableBody.innerHTML = `
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted py-4">
|
||||
Loading permissions…
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
fetch(endpoint, {
|
||||
headers: { 'Accept': 'application/json' },
|
||||
credentials: 'same-origin',
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Request failed with status ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((payload) => {
|
||||
clearError();
|
||||
renderPermissions(Array.isArray(payload?.permissions) ? payload.permissions : []);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
showError('Unable to load permissions.');
|
||||
destroyDataTable();
|
||||
tableBody.innerHTML = `
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-danger py-4">
|
||||
Failed to load permissions.
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
};
|
||||
|
||||
fetchPermissions();
|
||||
});
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
Reference in New Issue
Block a user