Compare commits
3 Commits
1ab374531c
...
67a7d769f0
| Author | SHA1 | Date | |
|---|---|---|---|
| 67a7d769f0 | |||
| 84b104a501 | |||
| ff109a710c |
@@ -120,7 +120,7 @@ try {
|
|||||||
$stmt = $conn->prepare("UPDATE status_transitions SET
|
$stmt = $conn->prepare("UPDATE status_transitions SET
|
||||||
from_status = ?, to_status = ?, requires_comment = ?, requires_admin = ?, is_active = ?
|
from_status = ?, to_status = ?, requires_comment = ?, requires_admin = ?, is_active = ?
|
||||||
WHERE transition_id = ?");
|
WHERE transition_id = ?");
|
||||||
$stmt->bind_param('ssiiiii',
|
$stmt->bind_param('ssiiii',
|
||||||
$data['from_status'],
|
$data['from_status'],
|
||||||
$data['to_status'],
|
$data['to_status'],
|
||||||
$data['requires_comment'] ?? 0,
|
$data['requires_comment'] ?? 0,
|
||||||
|
|||||||
@@ -686,7 +686,9 @@ function closeBulkPriorityModal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function performBulkPriority() {
|
function performBulkPriority() {
|
||||||
const priority = document.getElementById('bulkPriority').value;
|
const priorityEl = document.getElementById('bulkPriority');
|
||||||
|
if (!priorityEl) return;
|
||||||
|
const priority = priorityEl.value;
|
||||||
const ticketIds = getSelectedTicketIds();
|
const ticketIds = getSelectedTicketIds();
|
||||||
|
|
||||||
if (!priority) {
|
if (!priority) {
|
||||||
@@ -789,7 +791,9 @@ function closeBulkStatusModal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function performBulkStatusChange() {
|
function performBulkStatusChange() {
|
||||||
const status = document.getElementById('bulkStatus').value;
|
const bulkStatusEl = document.getElementById('bulkStatus');
|
||||||
|
if (!bulkStatusEl) return;
|
||||||
|
const status = bulkStatusEl.value;
|
||||||
const ticketIds = getSelectedTicketIds();
|
const ticketIds = getSelectedTicketIds();
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@@ -986,7 +990,9 @@ function closeQuickStatusModal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function performQuickStatusChange(ticketId) {
|
function performQuickStatusChange(ticketId) {
|
||||||
const newStatus = document.getElementById('quickStatusSelect').value;
|
const quickStatusEl = document.getElementById('quickStatusSelect');
|
||||||
|
if (!quickStatusEl) return;
|
||||||
|
const newStatus = quickStatusEl.value;
|
||||||
|
|
||||||
lt.api.post('/api/update_ticket.php', { ticket_id: ticketId, status: newStatus })
|
lt.api.post('/api/update_ticket.php', { ticket_id: ticketId, status: newStatus })
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
|||||||
+1
-1
@@ -1528,7 +1528,7 @@ function submitReply(parentCommentId) {
|
|||||||
<div class="comment-text" id="comment-text-${data.comment_id}" ${isMarkdownEnabled ? 'data-markdown' : ''}>
|
<div class="comment-text" id="comment-text-${data.comment_id}" ${isMarkdownEnabled ? 'data-markdown' : ''}>
|
||||||
${displayText}
|
${displayText}
|
||||||
</div>
|
</div>
|
||||||
<textarea class="comment-edit-raw" id="comment-raw-${data.comment_id}" style="display:none;">${commentText.replace(/</g, '<').replace(/>/g, '>')}</textarea>
|
<textarea class="comment-edit-raw is-hidden" id="comment-raw-${data.comment_id}">${commentText.replace(/</g, '<').replace(/>/g, '>')}</textarea>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -136,10 +136,16 @@ class DashboardController {
|
|||||||
|
|
||||||
// Validate user ID filters
|
// Validate user ID filters
|
||||||
$createdBy = $this->validateUserId($_GET['created_by'] ?? null);
|
$createdBy = $this->validateUserId($_GET['created_by'] ?? null);
|
||||||
$assignedTo = $this->validateUserId($_GET['assigned_to'] ?? null);
|
|
||||||
|
|
||||||
if ($createdBy !== null) $filters['created_by'] = $createdBy;
|
if ($createdBy !== null) $filters['created_by'] = $createdBy;
|
||||||
|
|
||||||
|
// assigned_to accepts a numeric user ID or the special string 'unassigned'
|
||||||
|
$assignedToRaw = $_GET['assigned_to'] ?? null;
|
||||||
|
if ($assignedToRaw === 'unassigned') {
|
||||||
|
$filters['assigned_to'] = 'unassigned';
|
||||||
|
} else {
|
||||||
|
$assignedTo = $this->validateUserId($assignedToRaw);
|
||||||
if ($assignedTo !== null) $filters['assigned_to'] = $assignedTo;
|
if ($assignedTo !== null) $filters['assigned_to'] = $assignedTo;
|
||||||
|
}
|
||||||
|
|
||||||
// Get tickets with pagination, sorting, search, and advanced filters
|
// Get tickets with pagination, sorting, search, and advanced filters
|
||||||
$result = $this->ticketModel->getAllTickets($page, $limit, $status, $sortColumn, $sortDirection, $category, $type, $search, $filters, $GLOBALS['currentUser'] ?? []);
|
$result = $this->ticketModel->getAllTickets($page, $limit, $status, $sortColumn, $sortDirection, $category, $type, $search, $filters, $GLOBALS['currentUser'] ?? []);
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ include __DIR__ . '/layout_header.php';
|
|||||||
<p id="visibilityHint" class="lt-form-hint">Everyone who is logged in can view this ticket.</p>
|
<p id="visibilityHint" class="lt-form-hint">Everyone who is logged in can view this ticket.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="visibilityGroupsContainer" class="lt-form-group is-hidden" aria-live="polite">
|
<div id="visibilityGroupsContainer" class="lt-form-group is-hidden" aria-live="polite" aria-describedby="visibilityGroupsHint">
|
||||||
<label class="lt-label lt-text-cyan">Allowed Groups</label>
|
<label class="lt-label lt-text-cyan">Allowed Groups</label>
|
||||||
<div class="visibility-groups-list lt-flex lt-flex-wrap lt-flex-gap-sm">
|
<div class="visibility-groups-list lt-flex lt-flex-wrap lt-flex-gap-sm">
|
||||||
<?php
|
<?php
|
||||||
@@ -205,7 +205,7 @@ include __DIR__ . '/layout_header.php';
|
|||||||
<span class="lt-text-muted lt-text-sm">No groups available</span>
|
<span class="lt-text-muted lt-text-sm">No groups available</span>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</div>
|
</div>
|
||||||
<p class="lt-form-hint lt-form-hint--warn">Select at least one group for Internal visibility.</p>
|
<p id="visibilityGroupsHint" class="lt-form-hint lt-form-hint--warn">Select at least one group for Internal visibility.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ include __DIR__ . '/layout_header.php';
|
|||||||
<div class="workload-item">
|
<div class="workload-item">
|
||||||
<div class="lt-avatar lt-avatar--sm <?= $avatarColor ?>" aria-hidden="true" title="<?= htmlspecialchars($name) ?>">
|
<div class="lt-avatar lt-avatar--sm <?= $avatarColor ?>" aria-hidden="true" title="<?= htmlspecialchars($name) ?>">
|
||||||
<?php if ($userId > 0): ?>
|
<?php if ($userId > 0): ?>
|
||||||
<img src="/api/user_avatar.php?user_id=<?= $userId ?>" alt="" class="lt-avatar-img" onerror="this.style.display='none'">
|
<img src="/api/user_avatar.php?user_id=<?= $userId ?>" alt="" class="lt-avatar-img">
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<span class="lt-avatar-initials"><?= htmlspecialchars($initials) ?></span>
|
<span class="lt-avatar-initials"><?= htmlspecialchars($initials) ?></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1269,7 +1269,7 @@ if (advForm) advForm.addEventListener('submit', performAdvancedSearch);
|
|||||||
(age ? '<div class="lt-kv-row"><span class="lt-kv-label">Age</span><span class="lt-kv-value">' + esc(age) + '</span></div>' : '') +
|
(age ? '<div class="lt-kv-row"><span class="lt-kv-label">Age</span><span class="lt-kv-value">' + esc(age) + '</span></div>' : '') +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<p class="lt-text-muted lt-text-xs" style="text-align:center">Click "Open Full Ticket" for description, comments & attachments.</p>';
|
'<p class="lt-text-muted lt-text-xs lt-text-center">Click "Open Full Ticket" for description, comments & attachments.</p>';
|
||||||
|
|
||||||
lt.rightDrawer.open('ticketPreviewDrawer');
|
lt.rightDrawer.open('ticketPreviewDrawer');
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-13
@@ -212,12 +212,7 @@ $progressClass = $slaBreached ? 'lt-progress--red' : ($slaPct >= 75 ? 'lt-progr
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="lt-alert-close" aria-label="Dismiss"
|
<button type="button" class="lt-alert-close" data-action="dismiss-priority-banner" aria-label="Dismiss">✕</button>
|
||||||
onclick="(function(btn){
|
|
||||||
var id=btn.closest('[data-alert-id]').dataset.alertId;
|
|
||||||
try{sessionStorage.setItem('lt_dismissed_'+id,'1');}catch(e){}
|
|
||||||
btn.closest('.lt-alert').classList.add('dismissed');
|
|
||||||
})(this)">✕</button>
|
|
||||||
</div>
|
</div>
|
||||||
<script nonce="<?= htmlspecialchars($nonce, ENT_QUOTES, 'UTF-8') ?>">
|
<script nonce="<?= htmlspecialchars($nonce, ENT_QUOTES, 'UTF-8') ?>">
|
||||||
(function(){
|
(function(){
|
||||||
@@ -564,8 +559,7 @@ $progressClass = $slaBreached ? 'lt-progress--red' : ($slaPct >= 75 ? 'lt-progr
|
|||||||
<?php if ($commentUserId > 0): ?>
|
<?php if ($commentUserId > 0): ?>
|
||||||
<img src="/api/user_avatar.php?user_id=<?= $commentUserId ?>"
|
<img src="/api/user_avatar.php?user_id=<?= $commentUserId ?>"
|
||||||
alt=""
|
alt=""
|
||||||
class="lt-avatar-img"
|
class="lt-avatar-img">
|
||||||
onerror="this.style.display='none'">
|
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<span class="lt-avatar-initials"><?= htmlspecialchars($initials) ?></span>
|
<span class="lt-avatar-initials"><?= htmlspecialchars($initials) ?></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -602,9 +596,8 @@ $progressClass = $slaBreached ? 'lt-progress--red' : ($slaPct >= 75 ? 'lt-progr
|
|||||||
? htmlspecialchars($comment['comment_text'])
|
? htmlspecialchars($comment['comment_text'])
|
||||||
: nl2br(htmlspecialchars($comment['comment_text'])) ?>
|
: nl2br(htmlspecialchars($comment['comment_text'])) ?>
|
||||||
</div>
|
</div>
|
||||||
<textarea class="lt-input lt-textarea comment-edit-raw"
|
<textarea class="lt-input lt-textarea comment-edit-raw is-hidden"
|
||||||
id="comment-raw-<?= $commentId ?>"
|
id="comment-raw-<?= $commentId ?>"
|
||||||
style="display:none"
|
|
||||||
aria-hidden="true"><?= htmlspecialchars($comment['comment_text']) ?></textarea>
|
aria-hidden="true"><?= htmlspecialchars($comment['comment_text']) ?></textarea>
|
||||||
</div>
|
</div>
|
||||||
<?php if (!empty($comment['replies'])): ?>
|
<?php if (!empty($comment['replies'])): ?>
|
||||||
@@ -978,7 +971,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
for (var i = 0; i < (w.display_name || '').length; i++) hash = ((hash << 5) - hash + (w.display_name || '').charCodeAt(i)) | 0;
|
for (var i = 0; i < (w.display_name || '').length; i++) hash = ((hash << 5) - hash + (w.display_name || '').charCodeAt(i)) | 0;
|
||||||
var color = avatarColors[Math.abs(hash) % 4];
|
var color = avatarColors[Math.abs(hash) % 4];
|
||||||
html += '<div class="lt-avatar lt-avatar--xs ' + color + '" title="' + lt.escHtml(w.display_name) + '" aria-label="' + lt.escHtml(w.display_name) + '">' +
|
html += '<div class="lt-avatar lt-avatar--xs ' + color + '" title="' + lt.escHtml(w.display_name) + '" aria-label="' + lt.escHtml(w.display_name) + '">' +
|
||||||
'<img src="/api/user_avatar.php?user_id=' + w.user_id + '" alt="" class="lt-avatar-img" onerror="this.style.display=\'none\'">' +
|
'<img src="/api/user_avatar.php?user_id=' + w.user_id + '" alt="" class="lt-avatar-img">' +
|
||||||
'<span class="lt-avatar-initials">' + lt.escHtml(initials) + '</span>' +
|
'<span class="lt-avatar-initials">' + lt.escHtml(initials) + '</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
});
|
});
|
||||||
@@ -1121,6 +1114,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
if (typeof editComment === 'function') editComment(parseInt(commentId, 10));
|
if (typeof editComment === 'function') editComment(parseInt(commentId, 10));
|
||||||
} else if (action === 'delete-comment' && commentId) {
|
} else if (action === 'delete-comment' && commentId) {
|
||||||
if (typeof deleteComment === 'function') deleteComment(parseInt(commentId, 10));
|
if (typeof deleteComment === 'function') deleteComment(parseInt(commentId, 10));
|
||||||
|
} else if (action === 'dismiss-priority-banner') {
|
||||||
|
var banner = target.closest('[data-alert-id]');
|
||||||
|
if (banner) {
|
||||||
|
try { sessionStorage.setItem('lt_dismissed_' + banner.dataset.alertId, '1'); } catch(ex) {}
|
||||||
|
banner.classList.add('dismissed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1237,7 +1236,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
' data-action="delete-comment" data-comment-id="' + commentId + '" aria-label="Delete comment">Del</button>' : '';
|
' data-action="delete-comment" data-comment-id="' + commentId + '" aria-label="Delete comment">Del</button>' : '';
|
||||||
var threadLine = parentId ? '<div class="thread-line" aria-hidden="true"></div>' : '';
|
var threadLine = parentId ? '<div class="thread-line" aria-hidden="true"></div>' : '';
|
||||||
var avatarImg = userId > 0 ?
|
var avatarImg = userId > 0 ?
|
||||||
'<img src="/api/user_avatar.php?user_id=' + userId + '" alt="" class="lt-avatar-img" onerror="this.style.display=\'none\'">' : '';
|
'<img src="/api/user_avatar.php?user_id=' + userId + '" alt="" class="lt-avatar-img">' : '';
|
||||||
|
|
||||||
var div = document.createElement('div');
|
var div = document.createElement('div');
|
||||||
div.className = 'comment ' + depthClass + ' ' + threadClass;
|
div.className = 'comment ' + depthClass + ' ' + threadClass;
|
||||||
@@ -1263,7 +1262,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
'<div class="comment-text" id="comment-text-' + commentId + '"' + (mdEnabled ? ' data-markdown data-rendered="1"' : '') + '>' +
|
'<div class="comment-text" id="comment-text-' + commentId + '"' + (mdEnabled ? ' data-markdown data-rendered="1"' : '') + '>' +
|
||||||
commentText +
|
commentText +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<textarea class="lt-input lt-textarea comment-edit-raw" id="comment-raw-' + commentId + '" style="display:none" aria-hidden="true">' +
|
'<textarea class="lt-input lt-textarea comment-edit-raw is-hidden" id="comment-raw-' + commentId + '" aria-hidden="true">' +
|
||||||
escapedRaw +
|
escapedRaw +
|
||||||
'</textarea>' +
|
'</textarea>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ include __DIR__ . '/../../views/layout_header.php';
|
|||||||
<td data-label="Label"><strong><?= htmlspecialchars($field['field_label']) ?></strong></td>
|
<td data-label="Label"><strong><?= htmlspecialchars($field['field_label']) ?></strong></td>
|
||||||
<td data-label="Type" class="lt-text-xs"><?= ucfirst($field['field_type']) ?></td>
|
<td data-label="Type" class="lt-text-xs"><?= ucfirst($field['field_type']) ?></td>
|
||||||
<td data-label="Category" class="lt-text-xs"><?= htmlspecialchars($field['category'] ?? 'All') ?></td>
|
<td data-label="Category" class="lt-text-xs"><?= htmlspecialchars($field['category'] ?? 'All') ?></td>
|
||||||
<td data-label="Required" style="text-align:center">
|
<td data-label="Required" class="lt-text-center">
|
||||||
<?= $field['is_required'] ? '<span class="lt-text-amber">✓</span>' : '<span class="lt-text-muted">—</span>' ?>
|
<?= $field['is_required'] ? '<span class="lt-text-amber">✓</span>' : '<span class="lt-text-muted">—</span>' ?>
|
||||||
</td>
|
</td>
|
||||||
<td data-label="Status">
|
<td data-label="Status">
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ include __DIR__ . '/../../views/layout_header.php';
|
|||||||
$toCount = 0;
|
$toCount = 0;
|
||||||
if (isset($workflows)) { foreach ($workflows as $w) { if ($w['from_status'] === $status) $toCount++; } }
|
if (isset($workflows)) { foreach ($workflows as $w) { if ($w['from_status'] === $status) $toCount++; } }
|
||||||
?>
|
?>
|
||||||
<div class="lt-card" style="text-align:center">
|
<div class="lt-card lt-text-center">
|
||||||
<span class="lt-status lt-status-<?= $slug ?>"><?= $status ?></span>
|
<span class="lt-status lt-status-<?= $slug ?>"><?= $status ?></span>
|
||||||
<div class="lt-text-xs lt-text-muted lt-mt-sm">→ <?= $toCount ?> transition<?= $toCount !== 1 ? 's' : '' ?></div>
|
<div class="lt-text-xs lt-text-muted lt-mt-sm">→ <?= $toCount ?> transition<?= $toCount !== 1 ? 's' : '' ?></div>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</div>
|
</div>
|
||||||
<p class="lt-text-xs lt-text-muted" style="margin-top:0.5rem">
|
<p class="lt-text-xs lt-text-muted lt-mt-sm">
|
||||||
Define which status transitions are allowed. This controls what options appear in the status dropdown on tickets.
|
Define which status transitions are allowed. This controls what options appear in the status dropdown on tickets.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -69,17 +69,17 @@ include __DIR__ . '/../../views/layout_header.php';
|
|||||||
<td data-label="From">
|
<td data-label="From">
|
||||||
<span class="lt-status lt-status-<?= $fromSlug ?>"><?= htmlspecialchars($wf['from_status']) ?></span>
|
<span class="lt-status lt-status-<?= $fromSlug ?>"><?= htmlspecialchars($wf['from_status']) ?></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="lt-text-amber lt-text-xs" style="text-align:center">→</td>
|
<td class="lt-text-amber lt-text-xs lt-text-center">→</td>
|
||||||
<td data-label="To">
|
<td data-label="To">
|
||||||
<span class="lt-status lt-status-<?= $toSlug ?>"><?= htmlspecialchars($wf['to_status']) ?></span>
|
<span class="lt-status lt-status-<?= $toSlug ?>"><?= htmlspecialchars($wf['to_status']) ?></span>
|
||||||
</td>
|
</td>
|
||||||
<td data-label="Req. Comment" style="text-align:center">
|
<td data-label="Req. Comment" class="lt-text-center">
|
||||||
<?= $wf['requires_comment'] ? '<span class="lt-text-cyan">✓</span>' : '<span class="lt-text-muted">—</span>' ?>
|
<?= $wf['requires_comment'] ? '<span class="lt-text-cyan">✓</span>' : '<span class="lt-text-muted">—</span>' ?>
|
||||||
</td>
|
</td>
|
||||||
<td data-label="Req. Admin" style="text-align:center">
|
<td data-label="Req. Admin" class="lt-text-center">
|
||||||
<?= $wf['requires_admin'] ? '<span class="lt-text-amber">✓</span>' : '<span class="lt-text-muted">—</span>' ?>
|
<?= $wf['requires_admin'] ? '<span class="lt-text-amber">✓</span>' : '<span class="lt-text-muted">—</span>' ?>
|
||||||
</td>
|
</td>
|
||||||
<td data-label="Active" style="text-align:center">
|
<td data-label="Active" class="lt-text-center">
|
||||||
<?= $wf['is_active']
|
<?= $wf['is_active']
|
||||||
? '<span class="lt-text-cyan">✓</span>'
|
? '<span class="lt-text-cyan">✓</span>'
|
||||||
: '<span class="lt-text-danger">✗</span>' ?>
|
: '<span class="lt-text-danger">✗</span>' ?>
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ include __DIR__ . '/../views/layout_header.php';
|
|||||||
<div class="lt-frame" style="max-width:32rem;margin:4rem auto">
|
<div class="lt-frame" style="max-width:32rem;margin:4rem auto">
|
||||||
<span class="lt-frame-bl">╚</span><span class="lt-frame-br">╝</span>
|
<span class="lt-frame-bl">╚</span><span class="lt-frame-br">╝</span>
|
||||||
<div class="lt-section-header lt-text-danger">[ 403 ] ACCESS DENIED</div>
|
<div class="lt-section-header lt-text-danger">[ 403 ] ACCESS DENIED</div>
|
||||||
<div class="lt-section-body" style="text-align:center">
|
<div class="lt-section-body lt-text-center">
|
||||||
<p class="lt-text-muted lt-mb-md">You do not have permission to access this resource.</p>
|
<p class="lt-text-muted lt-mb-md">You do not have permission to access this resource.</p>
|
||||||
<a href="/" class="lt-btn lt-btn-primary">← Dashboard</a>
|
<a href="/" class="lt-btn lt-btn-primary">← Dashboard</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ include __DIR__ . '/../views/layout_header.php';
|
|||||||
<div class="lt-frame" style="max-width:32rem;margin:4rem auto">
|
<div class="lt-frame" style="max-width:32rem;margin:4rem auto">
|
||||||
<span class="lt-frame-bl">╚</span><span class="lt-frame-br">╝</span>
|
<span class="lt-frame-bl">╚</span><span class="lt-frame-br">╝</span>
|
||||||
<div class="lt-section-header lt-text-amber">[ 404 ] NOT FOUND</div>
|
<div class="lt-section-header lt-text-amber">[ 404 ] NOT FOUND</div>
|
||||||
<div class="lt-section-body" style="text-align:center">
|
<div class="lt-section-body lt-text-center">
|
||||||
<p class="lt-text-muted lt-mb-md">The page you requested does not exist.</p>
|
<p class="lt-text-muted lt-mb-md">The page you requested does not exist.</p>
|
||||||
<a href="/" class="lt-btn lt-btn-primary">← Dashboard</a>
|
<a href="/" class="lt-btn lt-btn-primary">← Dashboard</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -166,7 +166,6 @@ $_lt_assetVer = $GLOBALS['config']['ASSET_VERSION'] ?? '20260329';
|
|||||||
<img src="/api/user_avatar.php?user_id=<?= $_lt_userId ?>"
|
<img src="/api/user_avatar.php?user_id=<?= $_lt_userId ?>"
|
||||||
alt=""
|
alt=""
|
||||||
class="lt-avatar-img"
|
class="lt-avatar-img"
|
||||||
onerror="this.style.display='none'">
|
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<span class="lt-avatar-initials"><?= htmlspecialchars($_lt_initials) ?></span>
|
<span class="lt-avatar-initials"><?= htmlspecialchars($_lt_initials) ?></span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user