Refactor: Complete codebase reorganization and modernization
- Split server.js routes into modular files (server/routes/) - departures.js: Departure data endpoints - sites.js: Site search and nearby sites - config.js: Configuration endpoints - Reorganized file structure following Node.js best practices: - Moved sites-config.json to config/sites.json - Moved API_RESPONSE_DOCUMENTATION.md to docs/ - Moved raspberry-pi-setup.sh to scripts/ - Archived legacy files to archive/ directory - Updated all code references to new file locations - Added archive/ to .gitignore to exclude legacy files from repo - Updated README.md with new structure and organization - All functionality tested and working correctly Version: 1.2.0
This commit is contained in:
165
public/js/components/Clock.js
Normal file
165
public/js/components/Clock.js
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* clock.js - A modular clock component for displaying time and date
|
||||
* Specifically configured for Stockholm, Sweden timezone
|
||||
*/
|
||||
|
||||
class Clock {
|
||||
constructor(options = {}) {
|
||||
// Default options
|
||||
this.options = {
|
||||
elementId: 'clock',
|
||||
timeFormat: 'HH:MM:SS',
|
||||
dateFormat: 'WEEKDAY, MONTH DAY, YEAR',
|
||||
timezone: 'Europe/Stockholm',
|
||||
updateInterval: 1000, // Update every second
|
||||
enableTimeSync: false, // Disable time sync by default to avoid CORS issues with local files
|
||||
...options
|
||||
};
|
||||
|
||||
this.element = document.getElementById(this.options.elementId);
|
||||
if (!this.element) {
|
||||
console.error(`Clock element with ID "${this.options.elementId}" not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create DOM structure
|
||||
this.createClockElements();
|
||||
|
||||
// Start the clock
|
||||
this.start();
|
||||
|
||||
// Sync with time server once a day (if enabled)
|
||||
if (this.options.enableTimeSync) {
|
||||
this.setupTimeSync();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the DOM elements for the clock
|
||||
*/
|
||||
createClockElements() {
|
||||
// Create container with appropriate styling
|
||||
this.element.classList.add('clock-container');
|
||||
|
||||
// Create time element
|
||||
this.timeElement = document.createElement('div');
|
||||
this.timeElement.classList.add('clock-time');
|
||||
this.element.appendChild(this.timeElement);
|
||||
|
||||
// Create a separate date element
|
||||
this.dateElement = document.createElement('div');
|
||||
this.dateElement.classList.add('clock-date');
|
||||
this.element.appendChild(this.dateElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the clock with the specified update interval
|
||||
*/
|
||||
start() {
|
||||
// Update immediately
|
||||
this.update();
|
||||
|
||||
// Set interval for updates
|
||||
this.intervalId = setInterval(() => this.update(), this.options.updateInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the clock
|
||||
*/
|
||||
stop() {
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
this.intervalId = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the clock display
|
||||
*/
|
||||
update() {
|
||||
const now = new Date();
|
||||
|
||||
// Format and display the time
|
||||
this.timeElement.innerHTML = this.formatTime(now);
|
||||
|
||||
// Format and display the date (with a separator)
|
||||
this.dateElement.textContent = " • " + this.formatDate(now);
|
||||
|
||||
// Make sure the date element is visible and inline
|
||||
this.dateElement.style.display = 'inline-block';
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the time according to the specified format
|
||||
* @param {Date} date - The date object to format
|
||||
* @returns {string} - The formatted time string
|
||||
*/
|
||||
formatTime(date) {
|
||||
const options = {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false,
|
||||
timeZone: this.options.timezone
|
||||
};
|
||||
|
||||
return date.toLocaleTimeString('sv-SE', options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the date according to the specified format
|
||||
* @param {Date} date - The date object to format
|
||||
* @returns {string} - The formatted date string
|
||||
*/
|
||||
formatDate(date) {
|
||||
const options = {
|
||||
weekday: 'long',
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: this.options.timezone
|
||||
};
|
||||
|
||||
return date.toLocaleDateString('sv-SE', options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up time synchronization with a time server
|
||||
* This will sync the time once a day to ensure accuracy
|
||||
*/
|
||||
setupTimeSync() {
|
||||
// Function to sync time
|
||||
const syncTime = async () => {
|
||||
try {
|
||||
// Check if we're running from a local file (which would cause CORS issues)
|
||||
if (window.location.protocol === 'file:') {
|
||||
console.log('Running from local file, skipping time sync to avoid CORS issues');
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the WorldTimeAPI to get the current time for Stockholm
|
||||
const response = await fetch('https://worldtimeapi.org/api/timezone/Europe/Stockholm');
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('Time synced with WorldTimeAPI:', data);
|
||||
|
||||
// The API already returns the time in the correct timezone
|
||||
// We just log it for verification purposes
|
||||
} catch (error) {
|
||||
console.log('Time sync skipped:', error.message);
|
||||
}
|
||||
};
|
||||
|
||||
// Sync immediately on load
|
||||
syncTime();
|
||||
|
||||
// Then sync once a day (86400000 ms = 24 hours)
|
||||
setInterval(syncTime, 86400000);
|
||||
}
|
||||
}
|
||||
|
||||
// Export the Clock class for use in other modules
|
||||
window.Clock = Clock;
|
||||
Reference in New Issue
Block a user