Baseline: The current state of the mess

This commit is contained in:
2026-05-05 17:35:02 -05:00
commit 1672f922fd
10 changed files with 2089 additions and 0 deletions
+158
View File
@@ -0,0 +1,158 @@
function ktc_open_edit_modal(id, ts, isToday) {
document.getElementById("ktc_edit_id").value=id;
const origTimeDisplay = document.getElementById("ktc_modal_orig_time");
if (origTimeDisplay) { origTimeDisplay.innerText = "Original: " + ts; }
document.getElementById("ktc_edit_modal").style.display="block";
}
// --- Guardrail 1: Punch Lockout ---
document.addEventListener('DOMContentLoaded', function() {
const btn = document.getElementById('ktc-punch-button');
const timerDiv = document.getElementById('ktc-timer');
const countdown = document.getElementById('ktc-countdown');
const form = document.getElementById('ktc-punch-form');
function updateTimer() {
const expiry = localStorage.getItem('ktc_lockout_expiry');
if (expiry) {
const now = Date.now();
const timeLeft = Math.ceil((expiry - now) / 1000);
if (timeLeft > 0) {
btn.disabled = true;
btn.style.opacity = '0.5';
btn.style.cursor = 'not-allowed';
timerDiv.style.display = 'block';
countdown.innerText = timeLeft;
setTimeout(updateTimer, 1000); // Check again in 1s
} else {
btn.disabled = false;
btn.style.opacity = '1';
btn.style.cursor = 'pointer';
timerDiv.style.display = 'none';
localStorage.removeItem('ktc_lockout_expiry');
}
}
}
// Initial check on page load
updateTimer();
form?.addEventListener('submit', function(e) {
// Set expiry for 60 seconds from now
const expiryTime = Date.now() + 60000;
localStorage.setItem('ktc_lockout_expiry', expiryTime);
// The page will now refresh, and updateTimer() will catch it on reload
});
});
// --- Guardrail 2: Modal Future-Time Validation ---
document.getElementById('ktc_proposed_time')?.addEventListener('input', function() {
const submitBtn = this.form.querySelector('button[type="submit"]');
// If the input has a 'max' attribute and value exceeds it
if (this.max && this.value > this.max) {
this.style.borderColor = 'red';
this.style.backgroundColor = '#fff0f0';
submitBtn.disabled = true;
submitBtn.style.opacity = '0.5';
} else {
this.style.borderColor = '#ccc';
this.style.backgroundColor = '#fff';
submitBtn.disabled = false;
submitBtn.style.opacity = '1';
}
});
function ktc_open_edit_modal(id, ts, isToday) {
document.getElementById("ktc_edit_id").value = id;
document.getElementById("ktc_modal_orig_time").innerText = "Original: " + ts;
const timeInput = document.getElementById("ktc_proposed_time");
if (isToday) {
// Set max to current Chicago time (HH:MM)
const now = new Date().toLocaleTimeString('en-GB', {
timeZone: ktcSovereignTZ,
hour: '2-digit',
minute: '2-digit'
});
timeInput.setAttribute('max', now);
} else {
timeInput.removeAttribute('max');
}
document.getElementById("ktc_edit_modal").style.display = "block";
}
// --- Guardrail 3: The Live Heartbeat ---
function ktc_start_heartbeat() {
const elapsedElement = document.getElementById('ktc-live-elapsed');
if (!elapsedElement) return;
// Pull the initial seconds we injected via PHP
let totalSeconds = parseInt(elapsedElement.getAttribute('data-seconds'));
setInterval(() => {
totalSeconds++;
// Math to format seconds into "Xh Ym Zs" or "Xh Ym"
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
// Update the display (Adding seconds for that "Live" feel)
elapsedElement.innerText = `${hours}h ${minutes}m ${seconds}s`;
}, 1000);
}
/**
* Consolidated KTC Heartbeat: Handles Real-Time Clock & Title Teleportation
*/
function ktc_init_digital_clock() {
const clock = document.getElementById('ktc-digital-clock');
if (!clock) return;
// Use a single interval to handle both time updates and UI placement
setInterval(() => {
// 1. Generate the time string using our Sovereign Timezone
const tz = typeof ktcSovereignTZ !== 'undefined' ? ktcSovereignTZ : 'America/Chicago';
const timeString = new Date().toLocaleTimeString('en-US', {
timeZone: tz,
hour12: true,
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
// 2. Update the display
clock.innerText = timeString;
// 3. One-time Teleport Check
// We only attempt to move it if it's not already inside the 'ktc-clock-target'
const pageTitle = document.querySelector('.entry-title, h1.page-title, h1');
const isAlreadyTeleported = document.getElementById('ktc-clock-target');
if (pageTitle && !isAlreadyTeleported) {
const target = document.createElement('span');
target.id = 'ktc-clock-target';
target.style.marginLeft = '20px';
target.style.fontSize = '0.6em';
target.style.verticalAlign = 'middle';
target.style.color = '#888'; // Subtle color for the clock in the title
pageTitle.appendChild(target);
target.appendChild(clock); // Physically moves the element in the DOM
// Cleanup the source container if it exists
const sourceContainer = document.getElementById('ktc-clock-teleport-source');
if (sourceContainer) sourceContainer.remove();
}
}, 1000);
}
// Initialize on DOM load
document.addEventListener('DOMContentLoaded', ktc_init_digital_clock);
// Initialize on load
document.addEventListener('DOMContentLoaded', ktc_start_heartbeat);
+196
View File
@@ -0,0 +1,196 @@
// --- Guardrail 1: Punch Lockout ---
document.addEventListener('DOMContentLoaded', function() {
const btn = document.getElementById('ktc-punch-button');
const timerDiv = document.getElementById('ktc-timer');
const countdown = document.getElementById('ktc-countdown');
const form = document.getElementById('ktc-punch-form');
// Initial check on page load
updateTimer();
function updateTimer() {
const expiry = localStorage.getItem('ktc_lockout_expiry');
if (expiry) {
const now = Date.now();
const timeLeft = Math.ceil((expiry - now) / 1000);
if (timeLeft > 0) {
btn.disabled = true;
btn.style.opacity = '0.5';
btn.style.cursor = 'not-allowed';
timerDiv.style.display = 'block';
countdown.innerText = timeLeft;
setTimeout(updateTimer, 1000); // Check again in 1s
} else {
btn.disabled = false;
btn.style.opacity = '1';
btn.style.cursor = 'pointer';
timerDiv.style.display = 'none';
localStorage.removeItem('ktc_lockout_expiry');
}
}
}
// --- New Listener for Admin Surgical Edits ---
document.addEventListener('click', function(e) {
// Check if the clicked element (or its parent) has our trigger class
const trigger = e.target.closest('.ktc-edit-trigger');
if (trigger) {
e.preventDefault(); // Stop the '#' jump
// Pull the data attributes we set in PHP
const logId = trigger.getAttribute('data-log-id');
const timestamp = trigger.getAttribute('data-current-time');
// Determine if it's "Today" for the future-time guardrail
// Simple check: does the date string match today's YYYY-MM-DD?
const todayStr = new Date().toISOString().split('T')[0];
const isToday = timestamp.includes(todayStr);
// Fire your existing function
ktc_open_edit_modal(logId, timestamp, isToday);
}
});
const body = document.querySelector('body');
if (body) {
body.addEventListener('click', function(e) {
// Check if the clicked element is our edit link
if (e.target && e.target.classList.contains('ktc-edit-trigger')) {
e.preventDefault();
const logId = e.target.getAttribute('data-log-id');
const currentTime = e.target.getAttribute('data-current-time');
// Extract HH:MM for the time input (expects 24hr format HH:MM)
// Assuming timestamp format: "2026-05-04 14:30:00"
const timeParts = currentTime.split(' ');
const rawTime = timeParts.length > 1 ? timeParts[1].substring(0, 5) : '';
// Call the existing modal function
ktc_open_edit_modal(logId, currentTime, true, rawTime);
}
});
}
form?.addEventListener('submit', function(e) {
// Set expiry for 60 seconds from now
const expiryTime = Date.now() + 60000;
localStorage.setItem('ktc_lockout_expiry', expiryTime);
// The page will now refresh, and updateTimer() will catch it on reload
});
});
// --- Guardrail 2: Modal Future-Time Validation ---
document.getElementById('ktc_proposed_time')?.addEventListener('input', function() {
const submitBtn = this.form.querySelector('button[type="submit"]');
// If the input has a 'max' attribute and value exceeds it
if (this.max && this.value > this.max) {
this.style.borderColor = 'red';
this.style.backgroundColor = '#fff0f0';
submitBtn.disabled = true;
submitBtn.style.opacity = '0.5';
} else {
this.style.borderColor = '#ccc';
this.style.backgroundColor = '#fff';
submitBtn.disabled = false;
submitBtn.style.opacity = '1';
}
});
function ktc_open_edit_modal(id, ts, isToday) {
document.getElementById("ktc_edit_id").value = id;
document.getElementById("ktc_modal_orig_time").innerText = "Original: " + ts;
const timeInput = document.getElementById("ktc_proposed_time");
if (isToday) {
// Set max to current Chicago time (HH:MM)
const now = new Date().toLocaleTimeString('en-GB', {
timeZone: ktcSovereignTZ,
hour: '2-digit',
minute: '2-digit'
});
timeInput.setAttribute('max', now);
} else {
timeInput.removeAttribute('max');
}
document.getElementById("ktc_edit_modal").style.display = "block";
}
// --- Guardrail 3: The Live Heartbeat ---
function ktc_start_heartbeat() {
const elapsedElement = document.getElementById('ktc-live-elapsed');
if (!elapsedElement) return;
// Pull the initial seconds we injected via PHP
let totalSeconds = parseInt(elapsedElement.getAttribute('data-seconds'));
setInterval(() => {
totalSeconds++;
// Math to format seconds into "Xh Ym Zs" or "Xh Ym"
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
// Update the display (Adding seconds for that "Live" feel)
elapsedElement.innerText = `${hours}h ${minutes}m ${seconds}s`;
}, 1000);
}
/**
* Consolidated KTC Heartbeat: Handles Real-Time Clock & Title Teleportation
*/
function ktc_init_digital_clock() {
const clock = document.getElementById('ktc-digital-clock');
if (!clock) return;
// Use a single interval to handle both time updates and UI placement
setInterval(() => {
// 1. Generate the time string using our Sovereign Timezone
const tz = typeof ktcSovereignTZ !== 'undefined' ? ktcSovereignTZ : 'America/Chicago';
const timeString = new Date().toLocaleTimeString('en-US', {
timeZone: tz,
hour12: true,
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
// 2. Update the display
clock.innerText = timeString;
// 3. One-time Teleport Check
// We only attempt to move it if it's not already inside the 'ktc-clock-target'
const pageTitle = document.querySelector('.entry-title, h1.page-title, h1');
const isAlreadyTeleported = document.getElementById('ktc-clock-target');
if (pageTitle && !isAlreadyTeleported) {
const target = document.createElement('span');
target.id = 'ktc-clock-target';
target.style.marginLeft = '20px';
target.style.fontSize = '0.6em';
target.style.verticalAlign = 'middle';
target.style.color = '#888'; // Subtle color for the clock in the title
pageTitle.appendChild(target);
target.appendChild(clock); // Physically moves the element in the DOM
// Cleanup the source container if it exists
const sourceContainer = document.getElementById('ktc-clock-teleport-source');
if (sourceContainer) sourceContainer.remove();
}
}, 1000);
}
// Initialize on DOM load
document.addEventListener('DOMContentLoaded', ktc_init_digital_clock);
// Initialize on load
document.addEventListener('DOMContentLoaded', ktc_start_heartbeat);
+157
View File
@@ -0,0 +1,157 @@
function ktc_open_edit_modal(id, ts, isToday) {
document.getElementById("ktc_edit_id").value=id;
const origTimeDisplay = document.getElementById("ktc_modal_orig_time");
if (origTimeDisplay) { origTimeDisplay.innerText = "Original: " + ts; }
document.getElementById("ktc_edit_modal").style.display="block";
}
// --- Guardrail 1: Punch Lockout ---
document.addEventListener('DOMContentLoaded', function() {
const btn = document.getElementById('ktc-punch-button');
const timerDiv = document.getElementById('ktc-timer');
const countdown = document.getElementById('ktc-countdown');
const form = document.getElementById('ktc-punch-form');
function updateTimer() {
const expiry = localStorage.getItem('ktc_lockout_expiry');
if (expiry) {
const now = Date.now();
const timeLeft = Math.ceil((expiry - now) / 1000);
if (timeLeft > 0) {
btn.disabled = true;
btn.style.opacity = '0.5';
btn.style.cursor = 'not-allowed';
timerDiv.style.display = 'block';
countdown.innerText = timeLeft;
setTimeout(updateTimer, 1000); // Check again in 1s
} else {
btn.disabled = false;
btn.style.opacity = '1';
btn.style.cursor = 'pointer';
timerDiv.style.display = 'none';
localStorage.removeItem('ktc_lockout_expiry');
}
}
}
// Initial check on page load
updateTimer();
form?.addEventListener('submit', function(e) {
// Set expiry for 60 seconds from now
const expiryTime = Date.now() + 60000;
localStorage.setItem('ktc_lockout_expiry', expiryTime);
// The page will now refresh, and updateTimer() will catch it on reload
});
});
// --- Guardrail 2: Modal Future-Time Validation ---
document.getElementById('ktc_proposed_time')?.addEventListener('input', function() {
const submitBtn = this.form.querySelector('button[type="submit"]');
// If the input has a 'max' attribute and value exceeds it
if (this.max && this.value > this.max) {
this.style.borderColor = 'red';
this.style.backgroundColor = '#fff0f0';
submitBtn.disabled = true;
submitBtn.style.opacity = '0.5';
} else {
this.style.borderColor = '#ccc';
this.style.backgroundColor = '#fff';
submitBtn.disabled = false;
submitBtn.style.opacity = '1';
}
});
function ktc_open_edit_modal(id, ts, isToday) {
document.getElementById("ktc_edit_id").value = id;
document.getElementById("ktc_modal_orig_time").innerText = "Original: " + ts;
const timeInput = document.getElementById("ktc_proposed_time");
if (isToday) {
// Set max to current Chicago time (HH:MM)
const now = new Date().toLocaleTimeString('en-GB', {
timeZone: ktcSovereignTZ,
hour: '2-digit',
minute: '2-digit'
});
timeInput.setAttribute('max', now);
} else {
timeInput.removeAttribute('max');
}
document.getElementById("ktc_edit_modal").style.display = "block";
}
// --- Guardrail 3: The Live Heartbeat ---
function ktc_start_heartbeat() {
const elapsedElement = document.getElementById('ktc-live-elapsed');
if (!elapsedElement) return;
// Pull the initial seconds we injected via PHP
let totalSeconds = parseInt(elapsedElement.getAttribute('data-seconds'));
setInterval(() => {
totalSeconds++;
// Math to format seconds into "Xh Ym Zs" or "Xh Ym"
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
// Update the display (Adding seconds for that "Live" feel)
elapsedElement.innerText = `${hours}h ${minutes}m ${seconds}s`;
}, 1000);
}
function ktc_run_digital_clock() {
const clockElement = document.getElementById('ktc-digital-clock');
if (!clockElement) return;
setInterval(() => {
const now = new Date().toLocaleTimeString('en-US', {
timeZone: typeof ktcSovereignTZ !== 'undefined' ? ktcSovereignTZ : 'America/Chicago',
hour12: true,
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
clockElement.innerText = now;
}, 1000);
}
document.addEventListener('DOMContentLoaded', ktc_run_digital_clock);
function updateDigitalClock() {
const clock = document.getElementById('ktc-digital-clock');
if (!clock) return;
const tz = typeof ktcSovereignTZ !== 'undefined' ? ktcSovereignTZ : 'America/Chicago';
const timeString = new Date().toLocaleTimeString('en-US', {
timeZone: tz,
hour12: true,
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
clock.innerText = timeString;
// Teleport to Page Title (h1) if not already there
const pageTitle = document.querySelector('.entry-title, h1.page-title');
if (pageTitle && !document.getElementById('ktc-clock-target')) {
const target = document.createElement('span');
target.id = 'ktc-clock-target';
target.style.marginLeft = '20px';
target.style.fontSize = '0.6em';
target.style.verticalAlign = 'middle';
pageTitle.appendChild(target);
target.appendChild(clock); // Moves the element in the DOM
document.getElementById('ktc-clock-teleport-source').remove();
}
}
// Initialize on load
document.addEventListener('DOMContentLoaded', ktc_start_heartbeat);