Apply web_template gap analysis improvements (P1-P3)
P1-A: Fix CSP - add fonts.googleapis.com to style-src, fonts.gstatic.com to font-src
P1-B: CSRF token rotation - add rotateToken() to CsrfMiddleware; bootstrap.php rotates
after successful validation and stores in $GLOBALS['_new_csrf_token']; add
apiRespond() helper to append token to responses; lt.api interceptor in
layout_footer.php auto-updates window.CSRF_TOKEN from responses
P1-C: Styled 403/404 error views with TDS layout instead of raw text; index.php now
uses requireAdmin() helper eliminating 7 duplicated guard blocks (P3-D)
P2-A: Remove duplicate JS-generated keyboard help modal from keyboard-shortcuts.js;
'?' key now routes to static #lt-keys-help modal in footer
P2-B: Asset versioning driven by config ASSET_VERSION key; base.css and base.js get
?v= cache-busting in layout_header.php
P2-C: Add data-theme="dark" to <html> tag to prevent FOUC on light-mode users
P2-E: Escape status value in dashboard.js hover preview class attribute via lt.escHtml()
P2-F: Replace bespoke showLoadingOverlay() with lt-spinner / lt-loading-text from
base.css; add .lt-loading-overlay wrapper CSS to dashboard.css
P2-G: Add keyboard-shortcuts.js to all 7 admin views so J/K nav and ? help work
P3-A: APP_NAME, APP_SUBTITLE, APP_VERSION driven from config.php; layout header/footer
use config values instead of hardcoded strings
P3-G: Replace custom initTableSorting() with lt.sortTable.init() which manages aria-sort
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+17
-9
@@ -52,7 +52,7 @@
|
||||
<span class="lt-footer-sep">|</span>
|
||||
<button type="button" class="lt-footer-hint" data-action="show-keyboard-help" title="Show keyboard shortcuts (?)"><span class="lt-footer-key">[ ? ]</span> HELP</button>
|
||||
</nav>
|
||||
<span aria-label="Application version">TINKER TICKETS — TDS v1.2</span>
|
||||
<span aria-label="Application version"><?= htmlspecialchars($GLOBALS['config']['APP_NAME'] ?? 'TINKER TICKETS', ENT_QUOTES, 'UTF-8') ?> — TDS v<?= htmlspecialchars($GLOBALS['config']['APP_VERSION'] ?? '1.2', ENT_QUOTES, 'UTF-8') ?></span>
|
||||
</footer>
|
||||
|
||||
<!-- ================================================================
|
||||
@@ -131,7 +131,7 @@
|
||||
<!-- LT INIT — boot animation + global UI init (base.js handles keys/nav automatically) -->
|
||||
<script nonce="<?= htmlspecialchars($nonce, ENT_QUOTES, 'UTF-8') ?>">
|
||||
if (window.lt) {
|
||||
lt.init({ bootName: 'TINKER TICKETS' });
|
||||
lt.init({ bootName: <?= json_encode($GLOBALS['config']['APP_NAME'] ?? 'TINKER TICKETS', JSON_HEX_TAG) ?> });
|
||||
|
||||
// Theme toggle button
|
||||
var themeBtn = document.getElementById('lt-theme-btn');
|
||||
@@ -155,19 +155,27 @@
|
||||
]);
|
||||
}
|
||||
|
||||
// Patch lt.api mutating methods to auto-rotate CSRF token when server returns a new one
|
||||
if (window.lt && lt.api) {
|
||||
['post', 'put', 'patch', 'delete'].forEach(function(method) {
|
||||
if (typeof lt.api[method] !== 'function') return;
|
||||
var _orig = lt.api[method];
|
||||
lt.api[method] = function(url, body) {
|
||||
return _orig.call(lt.api, url, body).then(function(data) {
|
||||
if (data && data.csrf_token) window.CSRF_TOKEN = data.csrf_token;
|
||||
return data;
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Footer hint bar actions (keyboard help + settings — work on all pages)
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target.closest('[data-action]');
|
||||
if (!btn) return;
|
||||
var action = btn.getAttribute('data-action');
|
||||
if (action === 'show-keyboard-help') {
|
||||
if (typeof showKeyboardHelp === 'function') {
|
||||
showKeyboardHelp();
|
||||
} else if (window.lt) {
|
||||
var h = document.getElementById('lt-keys-help');
|
||||
if (h) lt.modal.open('lt-keys-help');
|
||||
else lt.toast.info('Keyboard shortcuts: ESC=close Ctrl+K=search ?=this help');
|
||||
}
|
||||
if (window.lt) lt.modal.open('lt-keys-help');
|
||||
} else if (action === 'open-settings' || action === 'open-settings-modal') {
|
||||
if (typeof openSettingsModal === 'function') {
|
||||
openSettingsModal();
|
||||
|
||||
Reference in New Issue
Block a user