214 lines
8.1 KiB
PHP
214 lines
8.1 KiB
PHP
<?= $this->extend('layout/management_layout') ?>
|
|
<?= $this->section('content') ?>
|
|
<div class="container-fluid"
|
|
data-roles-endpoint="<?= esc($rolesEndpoint ?? site_url('api/rolepermission/roles')) ?>">
|
|
<div class="wrapper">
|
|
<div class="content">
|
|
<h2 class="text-center mt-4 mb-3">List of Roles</h2>
|
|
|
|
<?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; ?>
|
|
|
|
<div class="mt-3 d-flex justify-content-end">
|
|
<a href="<?= site_url('roles/add') ?>" class="btn btn-success">
|
|
<i class="fas fa-plus"></i> Add New Role
|
|
</a>
|
|
<a href="<?= site_url('rolepermission/assign_role') ?>" class="btn btn-info ms-2">
|
|
<i class="fas fa-user-tag"></i> Assign Role to User
|
|
</a>
|
|
</div>
|
|
|
|
<div id="rolesAlert" class="alert alert-danger d-none mt-3" role="alert"></div>
|
|
|
|
<div class="table-responsive mt-3">
|
|
<table id="rolesTable" class="display table table-bordered table-striped align-middle">
|
|
<thead class="table-dark">
|
|
<tr>
|
|
<th>Role ID</th>
|
|
<th>Role Name</th>
|
|
<th>Description</th>
|
|
<th>Number of Users</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td colspan="5" class="text-center text-muted">Loading roles...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<br>
|
|
</div>
|
|
</div>
|
|
<?= $this->endSection() ?>
|
|
|
|
<?= $this->section('scripts') ?>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const container = document.querySelector('[data-roles-endpoint]');
|
|
if (!container) {
|
|
return;
|
|
}
|
|
|
|
const endpoint = container.dataset.rolesEndpoint;
|
|
const tableBody = document.querySelector('#rolesTable tbody');
|
|
const alertBox = document.getElementById('rolesAlert');
|
|
|
|
const hasDataTables = () =>
|
|
!!(window.jQuery && window.jQuery.fn && window.jQuery.fn.DataTable);
|
|
|
|
const destroyDataTable = () => {
|
|
if (!hasDataTables()) return;
|
|
if (window.jQuery.fn.DataTable.isDataTable('#rolesTable')) {
|
|
window.jQuery('#rolesTable').DataTable().clear().destroy();
|
|
}
|
|
};
|
|
|
|
const initDataTable = () => {
|
|
if (!hasDataTables()) return;
|
|
window.jQuery('#rolesTable').DataTable({
|
|
pageLength: 10,
|
|
lengthMenu: [5, 10, 25, 50, 100],
|
|
ordering: true,
|
|
columnDefs: [
|
|
{ orderable: false, targets: [4] },
|
|
],
|
|
});
|
|
};
|
|
|
|
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 renderRoles = (roles) => {
|
|
if (!tableBody) return;
|
|
|
|
destroyDataTable();
|
|
tableBody.innerHTML = '';
|
|
|
|
if (!Array.isArray(roles) || roles.length === 0) {
|
|
const row = document.createElement('tr');
|
|
const cell = document.createElement('td');
|
|
cell.colSpan = 5;
|
|
cell.classList.add('text-center', 'text-muted');
|
|
cell.textContent = 'No roles found.';
|
|
row.appendChild(cell);
|
|
tableBody.appendChild(row);
|
|
return;
|
|
}
|
|
|
|
roles.forEach((role) => {
|
|
const row = document.createElement('tr');
|
|
|
|
const idCell = document.createElement('td');
|
|
idCell.textContent = role.id ?? '';
|
|
row.appendChild(idCell);
|
|
|
|
const nameCell = document.createElement('td');
|
|
nameCell.textContent = role.name ?? '';
|
|
row.appendChild(nameCell);
|
|
|
|
const descCell = document.createElement('td');
|
|
descCell.textContent = role.description ?? '';
|
|
row.appendChild(descCell);
|
|
|
|
const countCell = document.createElement('td');
|
|
countCell.textContent = Number.isFinite(role.user_count)
|
|
? role.user_count
|
|
: (role.user_count ?? 0);
|
|
row.appendChild(countCell);
|
|
|
|
const actionsCell = document.createElement('td');
|
|
actionsCell.innerHTML = `
|
|
<a href="<?= site_url('rolepermission/edit_role_permissions/') ?>${role.id}"
|
|
class="btn btn-sm btn-warning me-1">
|
|
<i class="fas fa-edit"></i> Update Role Permissions
|
|
</a>
|
|
<a href="<?= site_url('roles/edit/') ?>${role.id}"
|
|
class="btn btn-sm btn-primary me-1">
|
|
<i class="fas fa-cog"></i> Edit Role
|
|
</a>
|
|
<form action="<?= site_url('roles/delete/') ?>${role.id}" method="post" class="d-inline">
|
|
<?= csrf_field() ?>
|
|
<input type="hidden" name="_method" value="DELETE">
|
|
<button type="submit" class="btn btn-sm btn-danger"
|
|
onclick="return confirm('Are you sure you want to delete this role?')">
|
|
<i class="fas fa-trash"></i> Delete
|
|
</button>
|
|
</form>
|
|
`;
|
|
row.appendChild(actionsCell);
|
|
|
|
tableBody.appendChild(row);
|
|
});
|
|
|
|
initDataTable();
|
|
};
|
|
|
|
const fetchRoles = () => {
|
|
if (!endpoint) return;
|
|
|
|
tableBody.innerHTML = `
|
|
<tr>
|
|
<td colspan="5" class="text-center text-muted">Loading roles...</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();
|
|
|
|
const roles = Array.isArray(payload?.roles) ? payload.roles : [];
|
|
roles.forEach((role) => {
|
|
const count = Number(role.user_count ?? role.userCount ?? 0);
|
|
role.user_count = Number.isFinite(count) ? count : 0;
|
|
});
|
|
|
|
renderRoles(roles);
|
|
})
|
|
.catch((error) => {
|
|
console.error(error);
|
|
showError('Unable to load roles.');
|
|
destroyDataTable();
|
|
tableBody.innerHTML = `
|
|
<tr>
|
|
<td colspan="5" class="text-center text-danger">Failed to load roles.</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
};
|
|
|
|
fetchRoles();
|
|
});
|
|
</script>
|
|
<?= $this->endSection() ?>
|