From ba5fc194051364700d5000aa21df47de01fd9af3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Oct 2025 17:44:45 +0000 Subject: [PATCH] fix: Update clock display to show timezone-adjusted time ## Problem The time clock in the top right corner was displaying the user's local browser time instead of the timezone-adjusted time from the ESP32 server, even though the timezone was changed in settings. ## Root Cause The server was correctly sending timezone-adjusted time every 5 seconds in the `ntp_status` WebSocket message, but the client JavaScript was not updating the clock display with this data. The `updateNTPStatus()` function only updated the NTP status icon, ignoring the `data.time` field. ## Solution ### Client (data/script.js) - Modified `updateNTPStatus()` function to update the clock display (`timeElement.textContent`) with the timezone-adjusted time from `data.time` field (lines 935-938) ### Web Interface (data/index.html) - Updated cache-busting parameter from `?v=20251030` to `?v=20251030b` to ensure browsers reload the updated JavaScript ### Test Server (test-server/server.js) - Added `currentTimezone` variable to track selected timezone - Added `getFormattedTime()` helper function to format time in the selected timezone using JavaScript's Intl API - Added `set_timezone` action handler to allow timezone changes (admin only) - Updated NTP status broadcasts to use the selected timezone - Broadcasts updated time to all clients when timezone is changed ## Testing The fix can be tested with the test server: 1. Start test server: `cd test-server && npm start` 2. Login as admin (username: admin, password: admin) 3. Open Settings and change the timezone 4. Clock should immediately update to show the new timezone's time 5. Clock updates every 5 seconds with the correct timezone Fixes issue where clock displayed local time instead of selected timezone. --- data/index.html | 2 +- data/script.js | 5 +++++ test-server/server.js | 52 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/data/index.html b/data/index.html index 3655f47..63b0712 100644 --- a/data/index.html +++ b/data/index.html @@ -598,7 +598,7 @@

Import Hello Club Events

- + diff --git a/data/script.js b/data/script.js index 9efe12d..72d962e 100644 --- a/data/script.js +++ b/data/script.js @@ -931,6 +931,11 @@ function updateNTPStatus(data) { tooltip += `\nAuto-sync: every ${data.autoSyncInterval} min`; } ntpStatusElement.title = tooltip; + + // Update the time display with the timezone-adjusted time from the server + if (data.time && timeElement) { + timeElement.textContent = data.time; + } } else { ntpStatusElement.className = 'ntp-status ntp-error'; ntpStatusElement.textContent = '✗'; diff --git a/test-server/server.js b/test-server/server.js index cf9c32c..31867cf 100644 --- a/test-server/server.js +++ b/test-server/server.js @@ -50,6 +50,8 @@ let schedules = [ } ]; +let currentTimezone = 'Pacific/Auckland'; // Default timezone + let operators = [ { username: "operator1", password: "pass123" }, { username: "operator2", password: "test456" } @@ -124,6 +126,18 @@ function getNextWeekday(targetDay, hour, minute) { return result.toISOString(); } +// Helper function to get formatted time in selected timezone +function getFormattedTime() { + const now = new Date(); + return now.toLocaleTimeString('en-US', { + timeZone: currentTimezone, + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: true + }); +} + // Client tracking const clients = new Map(); let nextClientId = 1; @@ -149,8 +163,8 @@ wss.on('connection', (ws) => { sendMessage(ws, { event: 'ntp_status', synced: true, - time: new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true }), - timezone: 'Pacific/Auckland', + time: getFormattedTime(), + timezone: currentTimezone, dateTime: new Date().toISOString().replace('T', ' ').substring(0, 19), autoSyncInterval: 30 }); @@ -357,6 +371,34 @@ function handleMessage(clientId, ws, msg) { console.log('🔄 Factory reset completed'); break; + case 'set_timezone': + if (client.role !== 'admin') { + sendError(ws, 'Permission denied - admin only'); + return; + } + const newTimezone = msg.timezone; + if (!newTimezone) { + sendError(ws, 'Timezone required'); + return; + } + currentTimezone = newTimezone; + sendMessage(ws, { + event: 'timezone_changed', + timezone: currentTimezone, + message: 'Timezone updated successfully. Please refresh schedules.' + }); + // Broadcast updated NTP status with new timezone to all clients + broadcast({ + event: 'ntp_status', + synced: true, + time: getFormattedTime(), + timezone: currentTimezone, + dateTime: new Date().toISOString().replace('T', ' ').substring(0, 19), + autoSyncInterval: 30 + }); + console.log(`🌍 Timezone changed to: ${currentTimezone}`); + break; + // Hello Club Integration case 'get_helloclub_settings': if (client.role !== 'admin') { @@ -669,13 +711,13 @@ setInterval(() => { } }, 1000); -// Simulate NTP status updates +// Simulate NTP status updates (every 5 seconds) setInterval(() => { broadcast({ event: 'ntp_status', synced: true, - time: new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true }), - timezone: 'Pacific/Auckland', + time: getFormattedTime(), + timezone: currentTimezone, dateTime: new Date().toISOString().replace('T', ' ').substring(0, 19), autoSyncInterval: 30 });