use roles guards
This commit is contained in:
@@ -3,6 +3,8 @@ session_start();
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes_ac/ChartOfAccounts.php';
|
require '../../../assets/utils/classes_ac/ChartOfAccounts.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
if (empty($data['account_code']) || empty($data['account_name']) || empty($data['account_type'])) {
|
if (empty($data['account_code']) || empty($data['account_name']) || empty($data['account_type'])) {
|
||||||
$answer['message'] = 'Account code, name, and type are required';
|
$answer['message'] = 'Account code, name, and type are required';
|
||||||
exit(json_encode($answer));
|
exit(json_encode($answer));
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ session_start();
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes_ac/DepartmentManager.php';
|
require '../../../assets/utils/classes_ac/DepartmentManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
if (empty($data['dept_code']) || empty($data['dept_name'])) {
|
if (empty($data['dept_code']) || empty($data['dept_name'])) {
|
||||||
$answer['message'] = 'Department code and name are required';
|
$answer['message'] = 'Department code and name are required';
|
||||||
exit(json_encode($answer));
|
exit(json_encode($answer));
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ require '../../../assets/utils/classes_ac/posting/ReceiptPosting.php';
|
|||||||
require '../../../assets/utils/classes_ac/posting/PaymentPosting.php';
|
require '../../../assets/utils/classes_ac/posting/PaymentPosting.php';
|
||||||
require '../../../assets/utils/classes_ac/posting/PurchasePosting.php';
|
require '../../../assets/utils/classes_ac/posting/PurchasePosting.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
$doc_type = trim((string)($data['doc_type'] ?? ''));
|
$doc_type = trim((string)($data['doc_type'] ?? ''));
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
$formula_id = (int)($data['formula_id'] ?? 0) ?: null;
|
$formula_id = (int)($data['formula_id'] ?? 0) ?: null;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ session_start();
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes_ac/ChartOfAccounts.php';
|
require '../../../assets/utils/classes_ac/ChartOfAccounts.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
if (!$id) {
|
if (!$id) {
|
||||||
$answer['message'] = 'Missing id';
|
$answer['message'] = 'Missing id';
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ session_start();
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes_ac/DepartmentManager.php';
|
require '../../../assets/utils/classes_ac/DepartmentManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
if (!$id) { $answer['message'] = 'Missing id'; exit(json_encode($answer)); }
|
if (!$id) { $answer['message'] = 'Missing id'; exit(json_encode($answer)); }
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ require '../../../assets/utils/db_auth.php';
|
|||||||
require '../../../assets/utils/classes_ac/PostingWindowGuard.php';
|
require '../../../assets/utils/classes_ac/PostingWindowGuard.php';
|
||||||
require '../../../assets/utils/classes_ac/GlManager.php';
|
require '../../../assets/utils/classes_ac/GlManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
$gl_id = (int)($data['gl_id'] ?? 0);
|
$gl_id = (int)($data['gl_id'] ?? 0);
|
||||||
$reference = trim((string)($data['reference'] ?? ''));
|
$reference = trim((string)($data['reference'] ?? ''));
|
||||||
$description = trim((string)($data['description'] ?? ''));
|
$description = trim((string)($data['description'] ?? ''));
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ class UserManager {
|
|||||||
u.email,
|
u.email,
|
||||||
u.profile_picture,
|
u.profile_picture,
|
||||||
u.status,
|
u.status,
|
||||||
|
u.license,
|
||||||
(m.invite_token IS NOT NULL) AS is_pending_invite
|
(m.invite_token IS NOT NULL) AS is_pending_invite
|
||||||
FROM company_map_user m
|
FROM company_map_user m
|
||||||
JOIN user u ON u.user_id = m.user_id
|
JOIN user u ON u.user_id = m.user_id
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
$current_page = basename($_SERVER['PHP_SELF']);
|
$current_page = basename($_SERVER['PHP_SELF']);
|
||||||
$setting_role = $_SESSION['login_role'] ?? 'viewer';
|
$setting_role = $_SESSION['login_role'] ?? 'viewer';
|
||||||
$setting_can_admin = in_array($setting_role, ['owner', 'admin'], true);
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- SIDEBAR -->
|
<!-- SIDEBAR -->
|
||||||
@@ -38,15 +37,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<?php if ($setting_can_admin): ?>
|
<li>
|
||||||
<li>
|
<a class="nav-link <?php echo $current_page === 'users.php' ? 'active' : ''; ?>"
|
||||||
<a class="nav-link <?php echo $current_page === 'users.php' ? 'active' : ''; ?>"
|
href="<?php echo $server_url?>setting/users.php">
|
||||||
href="<?php echo $server_url?>setting/users.php">
|
<i class="ti ti-users"></i>
|
||||||
<i class="ti ti-users"></i>
|
<span class="nav-text">Users Access</span>
|
||||||
<span class="nav-text">Users Access</span>
|
</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a class="nav-link <?php echo $current_page === 'smtp.php' ? 'active' : ''; ?>"
|
<a class="nav-link <?php echo $current_page === 'smtp.php' ? 'active' : ''; ?>"
|
||||||
@@ -56,15 +53,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<?php if ($setting_can_admin): ?>
|
<li>
|
||||||
<li>
|
<a class="nav-link <?php echo $current_page === 'system_config.php' ? 'active' : ''; ?>"
|
||||||
<a class="nav-link <?php echo $current_page === 'system_config.php' ? 'active' : ''; ?>"
|
href="<?php echo $server_url?>setting/system_config.php">
|
||||||
href="<?php echo $server_url?>setting/system_config.php">
|
<i class="ti ti-adjustments-cog"></i>
|
||||||
<i class="ti ti-adjustments-cog"></i>
|
<span class="nav-text">System Configuration</span>
|
||||||
<span class="nav-text">System Configuration</span>
|
</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<!-- Back -->
|
<!-- Back -->
|
||||||
<li class="nav-text-space mt-2">
|
<li class="nav-text-space mt-2">
|
||||||
|
|||||||
@@ -113,11 +113,23 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<label class="form-label">Password <span class="text-danger">*</span></label>
|
<label class="form-label">Password <span class="text-danger">*</span></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="password" class="form-control" id="password" placeholder="Choose a strong password">
|
<input type="password" class="form-control" id="password" placeholder="Choose a strong password"
|
||||||
|
oninput="on_password_input(this.value)">
|
||||||
<button class="btn btn-outline-secondary toggle-pw" type="button" data-target="password">
|
<button class="btn btn-outline-secondary toggle-pw" type="button" data-target="password">
|
||||||
<i class="ti ti-eye"></i>
|
<i class="ti ti-eye"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="progress" style="height:5px;">
|
||||||
|
<div id="pw_strength_bar" class="progress-bar"
|
||||||
|
style="width:0%;transition:width .25s,background-color .25s;border-radius:4px;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between align-items-start mt-1 gap-2">
|
||||||
|
<small id="pw_strength_label" class="fw-semibold" style="white-space:nowrap;">—</small>
|
||||||
|
<small id="pw_feedback" class="text-muted text-end"></small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-text">Minimum required strength: <strong>Strong (3/4)</strong></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<label class="form-label">Confirm Password <span class="text-danger">*</span></label>
|
<label class="form-label">Confirm Password <span class="text-danger">*</span></label>
|
||||||
@@ -141,8 +153,36 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/zxcvbn@4.4.2/dist/zxcvbn.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
const STRENGTH_LEVELS = [
|
||||||
|
{ label: 'Very weak', color: '#dc3545', pct: 20 },
|
||||||
|
{ label: 'Weak', color: '#fd7e14', pct: 40 },
|
||||||
|
{ label: 'Fair', color: '#ffc107', pct: 60 },
|
||||||
|
{ label: 'Strong', color: '#198754', pct: 80 },
|
||||||
|
{ label: 'Very strong', color: '#0d6efd', pct: 100 },
|
||||||
|
];
|
||||||
|
|
||||||
|
var pw_score = -1;
|
||||||
|
|
||||||
|
function on_password_input(pw) {
|
||||||
|
if (!pw) {
|
||||||
|
pw_score = -1;
|
||||||
|
$('#pw_strength_bar').css({ width: '0%', backgroundColor: '' });
|
||||||
|
$('#pw_strength_label').text('—').css('color', '');
|
||||||
|
$('#pw_feedback').text('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const user_inputs = [$('#name').val(), $('#surname').val(), $('#username').val()].filter(Boolean);
|
||||||
|
const result = zxcvbn(pw, user_inputs);
|
||||||
|
pw_score = result.score;
|
||||||
|
const lvl = STRENGTH_LEVELS[pw_score];
|
||||||
|
$('#pw_strength_bar').css({ width: lvl.pct + '%', backgroundColor: lvl.color });
|
||||||
|
$('#pw_strength_label').text(lvl.label).css('color', lvl.color);
|
||||||
|
$('#pw_feedback').text(result.feedback.warning || result.feedback.suggestions[0] || '');
|
||||||
|
}
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
$(document).on('click', '.toggle-pw', function () {
|
$(document).on('click', '.toggle-pw', function () {
|
||||||
const $input = $('#' + $(this).data('target'));
|
const $input = $('#' + $(this).data('target'));
|
||||||
@@ -164,6 +204,11 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pw_score < 3) {
|
||||||
|
bootbox.alert('Password is too weak. Please choose a stronger password (Strong or above).');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (password !== confirm) {
|
if (password !== confirm) {
|
||||||
bootbox.alert('Passwords do not match.');
|
bootbox.alert('Passwords do not match.');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ require '../../../assets/utils/db_auth.php';
|
|||||||
require '../../../assets/utils/classes/OrderManager.php';
|
require '../../../assets/utils/classes/OrderManager.php';
|
||||||
require '../../../assets/utils/classes/QuotationManager.php';
|
require '../../../assets/utils/classes/QuotationManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$quotation_id = (int)($data['quotation_id'] ?? 0);
|
$quotation_id = (int)($data['quotation_id'] ?? 0);
|
||||||
$convert_items = $data['convert_items'] ?? [];
|
$convert_items = $data['convert_items'] ?? [];
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ require '../../../assets/utils/db_auth.php';
|
|||||||
require '../../../assets/utils/classes/UsageGuard.php';
|
require '../../../assets/utils/classes/UsageGuard.php';
|
||||||
require '../../../assets/utils/classes/OrderManager.php';
|
require '../../../assets/utils/classes/OrderManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$action = $data['action'] ?? '';
|
$action = $data['action'] ?? '';
|
||||||
$data['items'] = json_decode($data['items'] ?? '[]', true) ?: [];
|
$data['items'] = json_decode($data['items'] ?? '[]', true) ?: [];
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ session_start();
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/QuotationManager.php';
|
require '../../../assets/utils/classes/QuotationManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
$action = $data['action_type'] ?? '';
|
$action = $data['action_type'] ?? '';
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require '../../../assets/utils/db_auth.php';
|
|||||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||||
|
|
||||||
if (($data['action'] ?? '') === 'update') {
|
if (($data['action'] ?? '') === 'update') {
|
||||||
require_role($user_role, ['owner', 'admin']);
|
if ($user_role !== 'owner') { http_response_code(403); exit(json_encode(['success' => 0, 'message' => 'Only the owner can modify this setting.'])); }
|
||||||
}
|
}
|
||||||
|
|
||||||
$csm = new CompanySettingManager($pdo1, $company_id, $pdo2);
|
$csm = new CompanySettingManager($pdo1, $company_id, $pdo2);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/CompanyProfileManager.php';
|
require '../../../assets/utils/classes/CompanyProfileManager.php';
|
||||||
|
|
||||||
require_role($user_role, ['owner', 'admin']);
|
if ($user_role !== 'owner') { http_response_code(403); exit(json_encode(['success' => 0, 'message' => 'Only the owner can modify this setting.'])); }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$companyProfile = new CompanyProfileManager($pdo1, $company_id);
|
$companyProfile = new CompanyProfileManager($pdo1, $company_id);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/SmtpManager.php';
|
require '../../../assets/utils/classes/SmtpManager.php';
|
||||||
|
|
||||||
require_role($user_role, ['owner', 'admin']);
|
if ($user_role !== 'owner') { http_response_code(403); exit(json_encode(['success' => 0, 'message' => 'Only the owner can modify this setting.'])); }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$smtp = new SmtpManager($pdo1, $company_id, $method, $pinkey, $iv);
|
$smtp = new SmtpManager($pdo1, $company_id, $method, $pinkey, $iv);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/UserManager.php';
|
require '../../../assets/utils/classes/UserManager.php';
|
||||||
|
|
||||||
require_role($user_role, ['owner', 'admin']);
|
if ($user_role !== 'owner') { http_response_code(403); exit(json_encode(['success' => 0, 'message' => 'Only the owner can modify this setting.'])); }
|
||||||
|
|
||||||
$action = $data['action'] ?? '';
|
$action = $data['action'] ?? '';
|
||||||
$um = new UserManager($pdo1, $company_id, $user_id);
|
$um = new UserManager($pdo1, $company_id, $user_id);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/SmtpManager.php';
|
require '../../../assets/utils/classes/SmtpManager.php';
|
||||||
|
|
||||||
require_role($user_role, ['owner', 'admin']);
|
if ($user_role !== 'owner') { http_response_code(403); exit(json_encode(['success' => 0, 'message' => 'Only the owner can modify this setting.'])); }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$smtp = new SmtpManager($pdo1, $company_id, $method, $pinkey, $iv);
|
$smtp = new SmtpManager($pdo1, $company_id, $method, $pinkey, $iv);
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
|
||||||
http_response_code(403);
|
|
||||||
exit('Access denied.');
|
|
||||||
}
|
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|||||||
+49
-37
@@ -1,10 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
|
||||||
http_response_code(403);
|
|
||||||
exit('Access denied.');
|
|
||||||
}
|
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -23,7 +19,7 @@
|
|||||||
<h1 class="fs-3 mb-1">Users Access</h1>
|
<h1 class="fs-3 mb-1">Users Access</h1>
|
||||||
<p class="mb-0">Manage team members and their roles in your company</p>
|
<p class="mb-0">Manage team members and their roles in your company</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2" id="owner_actions" style="display:none!important;">
|
||||||
<button class="btn btn-primary" onclick="open_invite_modal()">
|
<button class="btn btn-primary" onclick="open_invite_modal()">
|
||||||
<i class="ti ti-user-plus me-1"></i>Add User
|
<i class="ti ti-user-plus me-1"></i>Add User
|
||||||
</button>
|
</button>
|
||||||
@@ -68,14 +64,15 @@
|
|||||||
<th class="ps-4">User</th>
|
<th class="ps-4">User</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Role</th>
|
<th>Role</th>
|
||||||
|
<th>License</th>
|
||||||
<th>App Access</th>
|
<th>App Access</th>
|
||||||
<th>Joined</th>
|
<th>Joined</th>
|
||||||
<th class="text-end pe-4">Actions</th>
|
<th class="text-end pe-4 owner-only-col">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="users_tbody">
|
<tbody id="users_tbody">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center py-5 text-muted">
|
<td colspan="7" class="text-center py-5 text-muted">
|
||||||
<i class="ti ti-loader-2 fs-2 d-block mb-2"></i>Loading…
|
<i class="ti ti-loader-2 fs-2 d-block mb-2"></i>Loading…
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -202,6 +199,7 @@
|
|||||||
const avatar_ph = '<?php echo $server_url?>assets/images/logo.svg';
|
const avatar_ph = '<?php echo $server_url?>assets/images/logo.svg';
|
||||||
const owner_app_access = '<?php echo htmlspecialchars($_SESSION['login_app_access'] ?? 'wms', ENT_QUOTES); ?>';
|
const owner_app_access = '<?php echo htmlspecialchars($_SESSION['login_app_access'] ?? 'wms', ENT_QUOTES); ?>';
|
||||||
const APP_REGISTRY = <?php echo json_encode($app_registry); ?>;
|
const APP_REGISTRY = <?php echo json_encode($app_registry); ?>;
|
||||||
|
const is_owner = user_role === 'owner';
|
||||||
let _users_data = [];
|
let _users_data = [];
|
||||||
|
|
||||||
|
|
||||||
@@ -209,6 +207,8 @@
|
|||||||
// On load
|
// On load
|
||||||
// ═══════════════════════════════════════════════
|
// ═══════════════════════════════════════════════
|
||||||
$(function () {
|
$(function () {
|
||||||
|
if (is_owner) $('#owner_actions').show();
|
||||||
|
else $('.owner-only-col').hide();
|
||||||
load_users();
|
load_users();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
if (!rows.length) {
|
if (!rows.length) {
|
||||||
tbody.html(`
|
tbody.html(`
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center py-5 text-muted">
|
<td colspan="${is_owner ? 7 : 6}" class="text-center py-5 text-muted">
|
||||||
<i class="ti ti-users-group fs-2 d-block mb-2"></i>No users found.
|
<i class="ti ti-users-group fs-2 d-block mb-2"></i>No users found.
|
||||||
</td>
|
</td>
|
||||||
</tr>`);
|
</tr>`);
|
||||||
@@ -252,8 +252,9 @@
|
|||||||
: `<span class="avatar-initials rounded-circle d-inline-flex align-items-center justify-content-center bg-light border fw-semibold text-secondary"
|
: `<span class="avatar-initials rounded-circle d-inline-flex align-items-center justify-content-center bg-light border fw-semibold text-secondary"
|
||||||
style="width:36px;height:36px;font-size:13px;">${initials(u.name, u.surname)}</span>`;
|
style="width:36px;height:36px;font-size:13px;">${initials(u.name, u.surname)}</span>`;
|
||||||
|
|
||||||
const role_badge = role_html(u.role);
|
const role_badge = role_html(u.role);
|
||||||
const access_badge = app_access_html(u.app_access);
|
const license_badge = license_html(u.license);
|
||||||
|
const access_badge = app_access_html(u.app_access);
|
||||||
|
|
||||||
const joined = u.created_at
|
const joined = u.created_at
|
||||||
? new Date(u.created_at).toLocaleDateString('en-GB', {day:'2-digit', month:'short', year:'numeric'})
|
? new Date(u.created_at).toLocaleDateString('en-GB', {day:'2-digit', month:'short', year:'numeric'})
|
||||||
@@ -262,30 +263,30 @@
|
|||||||
const is_pending = u.status === 'pending' && u.is_pending_invite == 1;
|
const is_pending = u.status === 'pending' && u.is_pending_invite == 1;
|
||||||
|
|
||||||
let actions = '';
|
let actions = '';
|
||||||
if (u.role === 'owner') {
|
if (is_owner && u.role !== 'owner') {
|
||||||
// owner — no actions
|
if (is_pending) {
|
||||||
} else if (is_pending) {
|
actions += `
|
||||||
actions += `
|
<button class="btn btn-sm btn-ghost-secondary" title="Resend invitation"
|
||||||
<button class="btn btn-sm btn-ghost-secondary" title="Resend invitation"
|
onclick="resend_invite(${u.map_id}, '${esc(u.email)}')">
|
||||||
onclick="resend_invite(${u.map_id}, '${esc(u.email)}')">
|
<i class="ti ti-send"></i>
|
||||||
<i class="ti ti-send"></i>
|
</button>`;
|
||||||
</button>`;
|
actions += `
|
||||||
actions += `
|
<button class="btn btn-sm btn-ghost-danger" title="Cancel invitation"
|
||||||
<button class="btn btn-sm btn-ghost-danger" title="Cancel invitation"
|
onclick="remove_user(${u.map_id}, '${esc(u.email)}')">
|
||||||
onclick="remove_user(${u.map_id}, '${esc(u.email)}')">
|
<i class="ti ti-user-minus"></i>
|
||||||
<i class="ti ti-user-minus"></i>
|
</button>`;
|
||||||
</button>`;
|
} else {
|
||||||
} else {
|
actions += `
|
||||||
actions += `
|
<button class="btn btn-sm btn-ghost-secondary" title="Edit access"
|
||||||
<button class="btn btn-sm btn-ghost-secondary" title="Edit access"
|
onclick="open_edit_modal(${u.map_id})">
|
||||||
onclick="open_edit_modal(${u.map_id})">
|
<i class="ti ti-shield-half"></i>
|
||||||
<i class="ti ti-shield-half"></i>
|
</button>`;
|
||||||
</button>`;
|
actions += `
|
||||||
actions += `
|
<button class="btn btn-sm btn-ghost-danger" title="Remove user"
|
||||||
<button class="btn btn-sm btn-ghost-danger" title="Remove user"
|
onclick="remove_user(${u.map_id}, '${esc(u.name)} ${esc(u.surname)}')">
|
||||||
onclick="remove_user(${u.map_id}, '${esc(u.name)} ${esc(u.surname)}')">
|
<i class="ti ti-user-minus"></i>
|
||||||
<i class="ti ti-user-minus"></i>
|
</button>`;
|
||||||
</button>`;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const display_role = is_pending
|
const display_role = is_pending
|
||||||
@@ -306,15 +307,17 @@
|
|||||||
</td>
|
</td>
|
||||||
<td style="color:#495057;">${esc(u.email)}</td>
|
<td style="color:#495057;">${esc(u.email)}</td>
|
||||||
<td>${display_role}</td>
|
<td>${display_role}</td>
|
||||||
|
<td>${license_badge}</td>
|
||||||
<td>${is_pending ? '—' : access_badge}</td>
|
<td>${is_pending ? '—' : access_badge}</td>
|
||||||
<td style="color:#495057;">${joined}</td>
|
<td style="color:#495057;">${joined}</td>
|
||||||
<td class="text-end pe-4">
|
<td class="text-end pe-4 owner-only-col">
|
||||||
<div class="d-flex justify-content-end gap-1">${actions}</div>
|
<div class="d-flex justify-content-end gap-1">${actions}</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
tbody.html(html);
|
tbody.html(html);
|
||||||
|
if (!is_owner) $('.owner-only-col').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -460,6 +463,15 @@
|
|||||||
.replace(/>/g,'>').replace(/"/g,'"');
|
.replace(/>/g,'>').replace(/"/g,'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function license_html(license) {
|
||||||
|
const map = {
|
||||||
|
owner: ['bg-success text-white', 'ti-crown', 'Owner'],
|
||||||
|
user: ['bg-light text-dark border', 'ti-user', 'User'],
|
||||||
|
};
|
||||||
|
const [cls, icon, label] = map[license] || ['bg-light text-dark border', 'ti-user', license || '—'];
|
||||||
|
return `<span class="badge ${cls}"><i class="ti ${icon} me-1"></i>${label}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
function role_html(role) {
|
function role_html(role) {
|
||||||
const map = {
|
const map = {
|
||||||
owner: ['bg-dark', 'ti-crown', 'Owner'],
|
owner: ['bg-dark', 'ti-crown', 'Owner'],
|
||||||
@@ -467,7 +479,7 @@
|
|||||||
staff: ['bg-info', 'ti-tool', 'Staff'],
|
staff: ['bg-info', 'ti-tool', 'Staff'],
|
||||||
viewer: ['bg-secondary', 'ti-eye', 'Viewer'],
|
viewer: ['bg-secondary', 'ti-eye', 'Viewer'],
|
||||||
};
|
};
|
||||||
const [cls, icon, label] = map[role] || ['bg-label-secondary', 'ti-user', 'Unknown'];
|
const [cls, icon, label] = map[role] || ['bg-secondary', 'ti-user', 'Unknown'];
|
||||||
return `<span class="badge ${cls}"><i class="ti ${icon} me-1"></i>${label}</span>`;
|
return `<span class="badge ${cls}"><i class="ti ${icon} me-1"></i>${label}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +493,7 @@
|
|||||||
return `<span class="badge bg-secondary"><i class="ti ti-apps me-1"></i>All Apps</span>`;
|
return `<span class="badge bg-secondary"><i class="ti ti-apps me-1"></i>All Apps</span>`;
|
||||||
}
|
}
|
||||||
const app = APP_REGISTRY[access];
|
const app = APP_REGISTRY[access];
|
||||||
if (!app) return `<span class="badge bg-label-secondary">${access || '—'}</span>`;
|
if (!app) return `<span class="badge bg-secondary">${access || '—'}</span>`;
|
||||||
return `<span class="badge ${app.color}"><i class="ti ${app.icon} me-1"></i>${app.label}</span>`;
|
return `<span class="badge ${app.color}"><i class="ti ${app.icon} me-1"></i>${app.label}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user